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 *************************************************************************/
27 #include "osl/diagnose.h"
28 #include "osl/doublecheckedlocking.h"
29 #include "rtl/ustrbuf.hxx"
31 #include "com/sun/star/beans/PropertyAttribute.hpp"
32 #include "com/sun/star/beans/PropertyValue.hpp"
33 #include "com/sun/star/beans/XPropertySet.hpp"
34 #include "com/sun/star/embed/ElementModes.hpp"
35 #include "com/sun/star/embed/XStorage.hpp"
36 #include "com/sun/star/embed/XTransactedObject.hpp"
37 #include "com/sun/star/io/XActiveDataSink.hpp"
38 #include "com/sun/star/io/XActiveDataStreamer.hpp"
39 #include "com/sun/star/lang/IllegalAccessException.hpp"
40 #include "com/sun/star/sdbc/XRow.hpp"
41 #include "com/sun/star/ucb/ContentAction.hpp"
42 #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
43 #include "com/sun/star/ucb/InsertCommandArgument.hpp"
44 #include "com/sun/star/ucb/InteractiveBadTransferURLException.hpp"
45 #include "com/sun/star/ucb/MissingInputStreamException.hpp"
46 #include "com/sun/star/ucb/MissingPropertiesException.hpp"
47 #include "com/sun/star/ucb/NameClash.hpp"
48 #include "com/sun/star/ucb/NameClashException.hpp"
49 #include "com/sun/star/ucb/OpenCommandArgument2.hpp"
50 #include "com/sun/star/ucb/OpenMode.hpp"
51 #include "com/sun/star/ucb/TransferInfo.hpp"
52 #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
53 #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
54 #include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
55 #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
56 #include "com/sun/star/ucb/XCommandInfo.hpp"
57 #include "com/sun/star/ucb/XPersistentPropertySet.hpp"
59 #include "comphelper/processfactory.hxx"
60 #include "ucbhelper/cancelcommandexecution.hxx"
61 #include "ucbhelper/contentidentifier.hxx"
62 #include "ucbhelper/propertyvalueset.hxx"
64 #include "tdoc_content.hxx"
65 #include "tdoc_resultset.hxx"
66 #include "tdoc_passwordrequest.hxx"
68 #include "../inc/urihelper.hxx"
70 using namespace com::sun::star
;
71 using namespace tdoc_ucp
;
74 static ContentType
lcl_getContentType( const OUString
& rType
)
76 if ( rType
== TDOC_ROOT_CONTENT_TYPE
)
78 else if ( rType
== TDOC_DOCUMENT_CONTENT_TYPE
)
80 else if ( rType
== TDOC_FOLDER_CONTENT_TYPE
)
82 else if ( rType
== TDOC_STREAM_CONTENT_TYPE
)
86 OSL_FAIL( "Content::Content - unsupported content type string" );
94 // Content Implementation.
99 // static ( "virtual" ctor )
100 Content
* Content::create(
101 const uno::Reference
< uno::XComponentContext
>& rxContext
,
102 ContentProvider
* pProvider
,
103 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
105 // Fail, if resource does not exist.
106 ContentProperties aProps
;
107 if ( !Content::loadData( pProvider
,
108 Uri( Identifier
->getContentIdentifier() ),
112 return new Content( rxContext
, pProvider
, Identifier
, aProps
);
116 // static ( "virtual" ctor )
117 Content
* Content::create(
118 const uno::Reference
< uno::XComponentContext
>& rxContext
,
119 ContentProvider
* pProvider
,
120 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
121 const ucb::ContentInfo
& Info
)
123 if ( Info
.Type
.isEmpty() )
126 if ( Info
.Type
!= TDOC_FOLDER_CONTENT_TYPE
&& Info
.Type
!= TDOC_STREAM_CONTENT_TYPE
)
128 OSL_FAIL( "Content::create - unsupported content type!" );
132 return new Content( rxContext
, pProvider
, Identifier
, Info
);
137 const uno::Reference
< uno::XComponentContext
> & rxContext
,
138 ContentProvider
* pProvider
,
139 const uno::Reference
< ucb::XContentIdentifier
> & Identifier
,
140 const ContentProperties
& rProps
)
141 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
143 m_eState( PERSISTENT
),
144 m_pProvider( pProvider
)
149 // ctor for a content just created via XContentCreator::createNewContent()
151 const uno::Reference
< uno::XComponentContext
>& rxContext
,
152 ContentProvider
* pProvider
,
153 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
154 const ucb::ContentInfo
& Info
)
155 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
156 m_aProps( lcl_getContentType( Info
.Type
), OUString() ), // no Title (yet)
157 m_eState( TRANSIENT
),
158 m_pProvider( pProvider
)
170 // XInterface methods.
175 void SAL_CALL
Content::acquire()
178 ContentImplHelper::acquire();
183 void SAL_CALL
Content::release()
186 ContentImplHelper::release();
191 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
)
192 throw ( uno::RuntimeException
, std::exception
)
194 uno::Any aRet
= ContentImplHelper::queryInterface( rType
);
196 if ( !aRet
.hasValue() )
198 aRet
= cppu::queryInterface(
199 rType
, static_cast< ucb::XContentCreator
* >( this ) );
200 if ( aRet
.hasValue() )
202 if ( !m_aProps
.isContentCreator() )
212 // XTypeProvider methods.
216 XTYPEPROVIDER_COMMON_IMPL( Content
);
220 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
221 throw( uno::RuntimeException
, std::exception
)
223 cppu::OTypeCollection
* pCollection
= 0;
225 if ( m_aProps
.isContentCreator() )
227 static cppu::OTypeCollection
* pFolderTypes
= 0;
229 pCollection
= pFolderTypes
;
232 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
234 pCollection
= pFolderTypes
;
237 static cppu::OTypeCollection
aCollection(
238 CPPU_TYPE_REF( lang::XTypeProvider
),
239 CPPU_TYPE_REF( lang::XServiceInfo
),
240 CPPU_TYPE_REF( lang::XComponent
),
241 CPPU_TYPE_REF( ucb::XContent
),
242 CPPU_TYPE_REF( ucb::XCommandProcessor
),
243 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
244 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
245 CPPU_TYPE_REF( beans::XPropertyContainer
),
246 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
247 CPPU_TYPE_REF( container::XChild
),
248 CPPU_TYPE_REF( ucb::XContentCreator
) ); // !!
249 pCollection
= &aCollection
;
250 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
251 pFolderTypes
= pCollection
;
255 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
260 static cppu::OTypeCollection
* pDocumentTypes
= 0;
262 pCollection
= pDocumentTypes
;
265 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
267 pCollection
= pDocumentTypes
;
270 static cppu::OTypeCollection
aCollection(
271 CPPU_TYPE_REF( lang::XTypeProvider
),
272 CPPU_TYPE_REF( lang::XServiceInfo
),
273 CPPU_TYPE_REF( lang::XComponent
),
274 CPPU_TYPE_REF( ucb::XContent
),
275 CPPU_TYPE_REF( ucb::XCommandProcessor
),
276 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
277 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
278 CPPU_TYPE_REF( beans::XPropertyContainer
),
279 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
280 CPPU_TYPE_REF( container::XChild
) );
281 pCollection
= &aCollection
;
282 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
283 pDocumentTypes
= pCollection
;
287 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
291 return (*pCollection
).getTypes();
296 // XServiceInfo methods.
301 OUString SAL_CALL
Content::getImplementationName()
302 throw( uno::RuntimeException
, std::exception
)
304 return OUString( "com.sun.star.comp.ucb.TransientDocumentsContent" );
309 uno::Sequence
< OUString
> SAL_CALL
Content::getSupportedServiceNames()
310 throw( uno::RuntimeException
, std::exception
)
312 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
314 uno::Sequence
< OUString
> aSNS( 1 );
316 if ( m_aProps
.getType() == STREAM
)
317 aSNS
.getArray()[ 0 ] = TDOC_STREAM_CONTENT_SERVICE_NAME
;
318 else if ( m_aProps
.getType() == FOLDER
)
319 aSNS
.getArray()[ 0 ] = TDOC_FOLDER_CONTENT_SERVICE_NAME
;
320 else if ( m_aProps
.getType() == DOCUMENT
)
321 aSNS
.getArray()[ 0 ] = TDOC_DOCUMENT_CONTENT_SERVICE_NAME
;
323 aSNS
.getArray()[ 0 ] = TDOC_ROOT_CONTENT_SERVICE_NAME
;
335 OUString SAL_CALL
Content::getContentType()
336 throw( uno::RuntimeException
, std::exception
)
338 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
339 return m_aProps
.getContentType();
344 uno::Reference
< ucb::XContentIdentifier
> SAL_CALL
345 Content::getIdentifier()
346 throw( uno::RuntimeException
, std::exception
)
349 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
352 if ( m_eState
== TRANSIENT
)
354 // Transient contents have no identifier.
355 return uno::Reference
< ucb::XContentIdentifier
>();
358 return ContentImplHelper::getIdentifier();
363 // XCommandProcessor methods.
368 uno::Any SAL_CALL
Content::execute(
369 const ucb::Command
& aCommand
,
370 sal_Int32
/*CommandId*/,
371 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
372 throw( uno::Exception
,
373 ucb::CommandAbortedException
,
374 uno::RuntimeException
, std::exception
)
378 if ( aCommand
.Name
== "getPropertyValues" )
384 uno::Sequence
< beans::Property
> Properties
;
385 if ( !( aCommand
.Argument
>>= Properties
) )
387 ucbhelper::cancelCommandExecution(
388 uno::makeAny( lang::IllegalArgumentException(
389 OUString( "Wrong argument type!" ),
390 static_cast< cppu::OWeakObject
* >( this ),
396 aRet
<<= getPropertyValues( Properties
);
398 else if ( aCommand
.Name
== "setPropertyValues" )
404 uno::Sequence
< beans::PropertyValue
> aProperties
;
405 if ( !( aCommand
.Argument
>>= aProperties
) )
407 ucbhelper::cancelCommandExecution(
408 uno::makeAny( lang::IllegalArgumentException(
409 OUString( "Wrong argument type!" ),
410 static_cast< cppu::OWeakObject
* >( this ),
416 if ( !aProperties
.getLength() )
418 ucbhelper::cancelCommandExecution(
419 uno::makeAny( lang::IllegalArgumentException(
420 OUString( "No properties!" ),
421 static_cast< cppu::OWeakObject
* >( this ),
427 aRet
<<= setPropertyValues( aProperties
, Environment
);
429 else if ( aCommand
.Name
== "getPropertySetInfo" )
432 // getPropertySetInfo
435 aRet
<<= getPropertySetInfo( Environment
);
437 else if ( aCommand
.Name
== "getCommandInfo" )
443 aRet
<<= getCommandInfo( Environment
);
445 else if ( aCommand
.Name
== "open" )
451 ucb::OpenCommandArgument2 aOpenCommand
;
452 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
454 ucbhelper::cancelCommandExecution(
455 uno::makeAny( lang::IllegalArgumentException(
456 OUString( "Wrong argument type!" ),
457 static_cast< cppu::OWeakObject
* >( this ),
463 aRet
= open( aOpenCommand
, Environment
);
465 else if ( aCommand
.Name
== "insert" )
468 // insert ( Supported by folders and streams only )
471 ContentType eType
= m_aProps
.getType();
472 if ( ( eType
!= FOLDER
) && ( eType
!= STREAM
) )
474 ucbhelper::cancelCommandExecution(
475 uno::makeAny( ucb::UnsupportedCommandException(
476 OUString( "insert command only supported by "
477 "folders and streams!" ),
478 static_cast< cppu::OWeakObject
* >( this ) ) ),
483 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
484 if ( eType
== STREAM
)
486 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
487 Uri
aParentUri( aUri
.getParentUri() );
488 if ( aParentUri
.isDocument() )
490 ucbhelper::cancelCommandExecution(
491 uno::makeAny( ucb::UnsupportedCommandException(
492 OUString( "insert command not supported by "
493 "streams that are direct children "
494 "of document root!" ),
495 static_cast< cppu::OWeakObject
* >(
502 ucb::InsertCommandArgument aArg
;
503 if ( !( aCommand
.Argument
>>= aArg
) )
505 ucbhelper::cancelCommandExecution(
506 uno::makeAny( lang::IllegalArgumentException(
507 OUString( "Wrong argument type!" ),
508 static_cast< cppu::OWeakObject
* >( this ),
514 sal_Int32 nNameClash
= aArg
.ReplaceExisting
515 ? ucb::NameClash::OVERWRITE
516 : ucb::NameClash::ERROR
;
517 insert( aArg
.Data
, nNameClash
, Environment
);
519 else if ( aCommand
.Name
== "delete" )
522 // delete ( Supported by folders and streams only )
526 osl::MutexGuard
aGuard( m_aMutex
);
528 ContentType eType
= m_aProps
.getType();
529 if ( ( eType
!= FOLDER
) && ( eType
!= STREAM
) )
531 ucbhelper::cancelCommandExecution(
532 uno::makeAny( ucb::UnsupportedCommandException(
533 OUString( "delete command only supported by "
534 "folders and streams!" ),
535 static_cast< cppu::OWeakObject
* >(
542 bool bDeletePhysical
= false;
543 aCommand
.Argument
>>= bDeletePhysical
;
544 destroy( bDeletePhysical
, Environment
);
546 // Remove own and all children's persistent data.
551 beans::PropertyValue(
554 uno::makeAny(m_xIdentifier
->
555 getContentIdentifier()),
556 beans::PropertyState_DIRECT_VALUE
));
557 ucbhelper::cancelCommandExecution(
558 ucb::IOErrorCode_CANT_WRITE
,
559 uno::Sequence
< uno::Any
>(&aProps
, 1),
561 OUString( "Cannot remove persistent data!" ),
566 // Remove own and all children's Additional Core Properties.
567 removeAdditionalPropertySet( true );
569 else if ( aCommand
.Name
== "transfer" )
572 // transfer ( Supported by document and folders only )
576 osl::MutexGuard
aGuard( m_aMutex
);
578 ContentType eType
= m_aProps
.getType();
579 if ( ( eType
!= FOLDER
) && ( eType
!= DOCUMENT
) )
581 ucbhelper::cancelCommandExecution(
582 uno::makeAny( ucb::UnsupportedCommandException(
583 OUString( "transfer command only supported "
584 "by folders and documents!" ),
585 static_cast< cppu::OWeakObject
* >(
592 ucb::TransferInfo aInfo
;
593 if ( !( aCommand
.Argument
>>= aInfo
) )
595 OSL_FAIL( "Wrong argument type!" );
596 ucbhelper::cancelCommandExecution(
597 uno::makeAny( lang::IllegalArgumentException(
598 OUString( "Wrong argument type!" ),
599 static_cast< cppu::OWeakObject
* >( this ),
605 transfer( aInfo
, Environment
);
607 else if ( aCommand
.Name
== "createNewContent" )
610 // createNewContent ( Supported by document and folders only )
614 osl::MutexGuard
aGuard( m_aMutex
);
616 ContentType eType
= m_aProps
.getType();
617 if ( ( eType
!= FOLDER
) && ( eType
!= DOCUMENT
) )
619 ucbhelper::cancelCommandExecution(
620 uno::makeAny( ucb::UnsupportedCommandException(
621 OUString( "createNewContent command only "
622 "supported by folders and "
624 static_cast< cppu::OWeakObject
* >(
631 ucb::ContentInfo aInfo
;
632 if ( !( aCommand
.Argument
>>= aInfo
) )
634 OSL_FAIL( "Wrong argument type!" );
635 ucbhelper::cancelCommandExecution(
636 uno::makeAny( lang::IllegalArgumentException(
637 OUString( "Wrong argument type!" ),
638 static_cast< cppu::OWeakObject
* >( this ),
644 aRet
<<= createNewContent( aInfo
);
649 // Unsupported command
652 ucbhelper::cancelCommandExecution(
653 uno::makeAny( ucb::UnsupportedCommandException(
655 static_cast< cppu::OWeakObject
* >( this ) ) ),
665 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
666 throw( uno::RuntimeException
, std::exception
)
672 // XContentCreator methods.
677 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
678 Content::queryCreatableContentsInfo()
679 throw( uno::RuntimeException
, std::exception
)
681 return m_aProps
.getCreatableContentsInfo();
686 uno::Reference
< ucb::XContent
> SAL_CALL
687 Content::createNewContent( const ucb::ContentInfo
& Info
)
688 throw( uno::RuntimeException
, std::exception
)
690 if ( m_aProps
.isContentCreator() )
692 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
694 if ( Info
.Type
.isEmpty() )
695 return uno::Reference
< ucb::XContent
>();
697 bool bCreateFolder
= Info
.Type
== TDOC_FOLDER_CONTENT_TYPE
;
699 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
700 // streams cannot be created as direct children of document root
701 if ( !bCreateFolder
&& ( m_aProps
.getType() == DOCUMENT
) )
703 OSL_FAIL( "Content::createNewContent - streams cannot be "
704 "created as direct children of document root!" );
705 return uno::Reference
< ucb::XContent
>();
708 if ( !bCreateFolder
&& Info
.Type
!= TDOC_STREAM_CONTENT_TYPE
)
710 OSL_FAIL( "Content::createNewContent - unsupported type!" );
711 return uno::Reference
< ucb::XContent
>();
714 OUString aURL
= m_xIdentifier
->getContentIdentifier();
716 OSL_ENSURE( !aURL
.isEmpty(),
717 "Content::createNewContent - empty identifier!" );
719 if ( ( aURL
.lastIndexOf( '/' ) + 1 ) != aURL
.getLength() )
723 aURL
+= "New_Folder";
725 aURL
+= "New_Stream";
727 uno::Reference
< ucb::XContentIdentifier
> xId
728 = new ::ucbhelper::ContentIdentifier( aURL
);
730 return create( m_xContext
, m_pProvider
, xId
, Info
);
734 OSL_FAIL( "createNewContent called on non-contentcreator object!" );
735 return uno::Reference
< ucb::XContent
>();
741 OUString
Content::getParentURL()
743 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
744 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
745 return aUri
.getParentUri();
749 uno::Reference
< ucb::XContentIdentifier
>
750 Content::makeNewIdentifier( const OUString
& rTitle
)
752 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
754 // Assemble new content identifier...
755 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
756 OUStringBuffer aNewURL
= aUri
.getParentUri();
757 aNewURL
.append( ::ucb_impl::urihelper::encodeSegment( rTitle
) );
760 uno::Reference
< ucb::XContentIdentifier
>(
761 new ::ucbhelper::ContentIdentifier( aNewURL
.makeStringAndClear() ) );
765 void Content::queryChildren( ContentRefList
& rChildren
)
767 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
769 // Only folders (root, documents, folders) have children.
770 if ( !m_aProps
.getIsFolder() )
773 // Obtain a list with a snapshot of all currently instantiated contents
774 // from provider and extract the contents which are direct children
777 ::ucbhelper::ContentRefList aAllContents
;
778 m_xProvider
->queryExistingContents( aAllContents
);
780 OUString aURL
= m_xIdentifier
->getContentIdentifier();
781 sal_Int32 nURLPos
= aURL
.lastIndexOf( '/' );
783 if ( nURLPos
!= ( aURL
.getLength() - 1 ) )
785 // No trailing slash found. Append.
789 sal_Int32 nLen
= aURL
.getLength();
791 ::ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
792 ::ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
796 ::ucbhelper::ContentImplHelperRef xChild
= (*it
);
798 = xChild
->getIdentifier()->getContentIdentifier();
800 // Is aURL a prefix of aChildURL?
801 if ( ( aChildURL
.getLength() > nLen
) &&
802 ( aChildURL
.startsWith( aURL
) ) )
804 sal_Int32 nPos
= nLen
;
805 nPos
= aChildURL
.indexOf( '/', nPos
);
807 if ( ( nPos
== -1 ) ||
808 ( nPos
== ( aChildURL
.getLength() - 1 ) ) )
810 // No further slashes / only a final slash. It's a child!
813 static_cast< Content
* >( xChild
.get() ) ) );
821 bool Content::exchangeIdentity(
822 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
827 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
829 uno::Reference
< ucb::XContent
> xThis
= this;
831 // Already persistent?
832 if ( m_eState
!= PERSISTENT
)
834 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
838 // Only folders and streams can be renamed -> exchange identity.
839 ContentType eType
= m_aProps
.getType();
840 if ( ( eType
== ROOT
) || ( eType
== DOCUMENT
) )
842 OSL_FAIL( "Content::exchangeIdentity - "
843 "Not supported by root or document!" );
847 // Exchange own identitity.
849 // Fail, if a content with given id already exists.
850 if ( !hasData( Uri( xNewId
->getContentIdentifier() ) ) )
852 OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
855 if ( exchange( xNewId
) )
857 if ( eType
== FOLDER
)
859 // Process instantiated children...
861 ContentRefList aChildren
;
862 queryChildren( aChildren
);
864 ContentRefList::const_iterator it
= aChildren
.begin();
865 ContentRefList::const_iterator end
= aChildren
.end();
869 ContentRef xChild
= (*it
);
871 // Create new content identifier for the child...
872 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
873 = xChild
->getIdentifier();
874 OUString aOldChildURL
875 = xOldChildId
->getContentIdentifier();
876 OUString aNewChildURL
877 = aOldChildURL
.replaceAt(
880 xNewId
->getContentIdentifier() );
881 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
882 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
884 if ( !xChild
->exchangeIdentity( xNewChildId
) )
894 OSL_FAIL( "Content::exchangeIdentity - "
895 "Panic! Cannot exchange identity!" );
901 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
902 const uno::Reference
< uno::XComponentContext
>& rxContext
,
903 const uno::Sequence
< beans::Property
>& rProperties
,
904 ContentProvider
* pProvider
,
905 const OUString
& rContentId
)
907 ContentProperties aData
;
908 if ( loadData( pProvider
, rContentId
, aData
) )
910 return getPropertyValues(
911 rxContext
, rProperties
, aData
, pProvider
, rContentId
);
915 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
916 = new ::ucbhelper::PropertyValueSet( rxContext
);
918 sal_Int32 nCount
= rProperties
.getLength();
921 const beans::Property
* pProps
= rProperties
.getConstArray();
922 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
923 xRow
->appendVoid( pProps
[ n
] );
926 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
932 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
933 const uno::Reference
< uno::XComponentContext
>& rxContext
,
934 const uno::Sequence
< beans::Property
>& rProperties
,
935 const ContentProperties
& rData
,
936 ContentProvider
* pProvider
,
937 const OUString
& rContentId
)
939 // Note: Empty sequence means "get values of all supported properties".
941 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
942 = new ::ucbhelper::PropertyValueSet( rxContext
);
944 sal_Int32 nCount
= rProperties
.getLength();
947 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
948 bool bTriedToGetAdditionalPropSet
= false;
950 const beans::Property
* pProps
= rProperties
.getConstArray();
951 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
953 const beans::Property
& rProp
= pProps
[ n
];
955 // Process Core properties.
957 if ( rProp
.Name
== "ContentType" )
959 xRow
->appendString ( rProp
, rData
.getContentType() );
961 else if ( rProp
.Name
== "Title" )
963 xRow
->appendString ( rProp
, rData
.getTitle() );
965 else if ( rProp
.Name
== "IsDocument" )
967 xRow
->appendBoolean( rProp
, rData
.getIsDocument() );
969 else if ( rProp
.Name
== "IsFolder" )
971 xRow
->appendBoolean( rProp
, rData
.getIsFolder() );
973 else if ( rProp
.Name
== "CreatableContentsInfo" )
976 rProp
, uno::makeAny( rData
.getCreatableContentsInfo() ) );
978 else if ( rProp
.Name
== "Storage" )
980 // Storage is only supported by folders.
981 ContentType eType
= rData
.getType();
982 if ( eType
== FOLDER
)
986 pProvider
->queryStorageClone( rContentId
) ) );
988 xRow
->appendVoid( rProp
);
990 else if ( rProp
.Name
== "DocumentModel" )
992 // DocumentModel is only supported by documents.
993 ContentType eType
= rData
.getType();
994 if ( eType
== DOCUMENT
)
998 pProvider
->queryDocumentModel( rContentId
) ) );
1000 xRow
->appendVoid( rProp
);
1004 // Not a Core Property! Maybe it's an Additional Core Property?!
1006 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
1009 = uno::Reference
< beans::XPropertySet
>(
1010 pProvider
->getAdditionalPropertySet( rContentId
,
1013 bTriedToGetAdditionalPropSet
= true;
1016 if ( xAdditionalPropSet
.is() )
1018 if ( !xRow
->appendPropertySetValue(
1022 // Append empty entry.
1023 xRow
->appendVoid( rProp
);
1028 // Append empty entry.
1029 xRow
->appendVoid( rProp
);
1036 // Append all Core Properties.
1037 xRow
->appendString (
1038 beans::Property( OUString("ContentType"),
1040 cppu::UnoType
<OUString
>::get(),
1041 beans::PropertyAttribute::BOUND
1042 | beans::PropertyAttribute::READONLY
),
1043 rData
.getContentType() );
1045 ContentType eType
= rData
.getType();
1047 xRow
->appendString (
1048 beans::Property( OUString("Title"),
1050 cppu::UnoType
<OUString
>::get(),
1051 // Title is read-only for root and documents.
1052 beans::PropertyAttribute::BOUND
|
1053 ( ( eType
== ROOT
) || ( eType
== DOCUMENT
)
1054 ? beans::PropertyAttribute::READONLY
1057 xRow
->appendBoolean(
1058 beans::Property( OUString("IsDocument"),
1060 cppu::UnoType
<bool>::get(),
1061 beans::PropertyAttribute::BOUND
1062 | beans::PropertyAttribute::READONLY
),
1063 rData
.getIsDocument() );
1064 xRow
->appendBoolean(
1065 beans::Property( OUString("IsFolder"),
1067 cppu::UnoType
<bool>::get(),
1068 beans::PropertyAttribute::BOUND
1069 | beans::PropertyAttribute::READONLY
),
1070 rData
.getIsFolder() );
1073 OUString("CreatableContentsInfo"),
1075 cppu::UnoType
<uno::Sequence
< ucb::ContentInfo
>>::get(),
1076 beans::PropertyAttribute::BOUND
1077 | beans::PropertyAttribute::READONLY
),
1078 uno::makeAny( rData
.getCreatableContentsInfo() ) );
1080 // Storage is only supported by folders.
1081 if ( eType
== FOLDER
)
1083 beans::Property( OUString("Storage"),
1085 cppu::UnoType
<embed::XStorage
>::get(),
1086 beans::PropertyAttribute::BOUND
1087 | beans::PropertyAttribute::READONLY
),
1088 uno::makeAny( pProvider
->queryStorageClone( rContentId
) ) );
1090 // DocumentModel is only supported by documents.
1091 if ( eType
== DOCUMENT
)
1093 beans::Property( OUString("DocumentModel"),
1095 cppu::UnoType
<frame::XModel
>::get(),
1096 beans::PropertyAttribute::BOUND
1097 | beans::PropertyAttribute::READONLY
),
1099 pProvider
->queryDocumentModel( rContentId
) ) );
1101 // Append all Additional Core Properties.
1103 uno::Reference
< beans::XPropertySet
> xSet(
1104 pProvider
->getAdditionalPropertySet( rContentId
, false ),
1106 xRow
->appendPropertySet( xSet
);
1109 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
1113 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
1114 const uno::Sequence
< beans::Property
>& rProperties
)
1116 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1117 return getPropertyValues( m_xContext
,
1121 m_xIdentifier
->getContentIdentifier() );
1125 uno::Sequence
< uno::Any
> Content::setPropertyValues(
1126 const uno::Sequence
< beans::PropertyValue
>& rValues
,
1127 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1128 throw( uno::Exception
)
1130 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1132 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
1133 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
1134 sal_Int32 nChanged
= 0;
1136 beans::PropertyChangeEvent aEvent
;
1137 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
1138 aEvent
.Further
= sal_False
;
1139 // aEvent.PropertyName =
1140 aEvent
.PropertyHandle
= -1;
1141 // aEvent.OldValue =
1142 // aEvent.NewValue =
1144 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1145 sal_Int32 nCount
= rValues
.getLength();
1147 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1148 bool bTriedToGetAdditionalPropSet
= false;
1150 bool bExchange
= false;
1152 sal_Int32 nTitlePos
= -1;
1154 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1156 const beans::PropertyValue
& rValue
= pValues
[ n
];
1158 if ( rValue
.Name
== "ContentType" )
1160 // Read-only property!
1161 aRet
[ n
] <<= lang::IllegalAccessException(
1162 OUString( "Property is read-only!" ),
1163 static_cast< cppu::OWeakObject
* >( this ) );
1165 else if ( rValue
.Name
== "IsDocument" )
1167 // Read-only property!
1168 aRet
[ n
] <<= lang::IllegalAccessException(
1169 OUString( "Property is read-only!" ),
1170 static_cast< cppu::OWeakObject
* >( this ) );
1172 else if ( rValue
.Name
== "IsFolder" )
1174 // Read-only property!
1175 aRet
[ n
] <<= lang::IllegalAccessException(
1176 OUString( "Property is read-only!" ),
1177 static_cast< cppu::OWeakObject
* >( this ) );
1179 else if ( rValue
.Name
== "CreatableContentsInfo" )
1181 // Read-only property!
1182 aRet
[ n
] <<= lang::IllegalAccessException(
1183 OUString( "Property is read-only!" ),
1184 static_cast< cppu::OWeakObject
* >( this ) );
1186 else if ( rValue
.Name
== "Title" )
1188 // Title is read-only for root and documents.
1189 ContentType eType
= m_aProps
.getType();
1190 if ( ( eType
== ROOT
) || ( eType
== DOCUMENT
) )
1192 aRet
[ n
] <<= lang::IllegalAccessException(
1193 OUString( "Property is read-only!" ),
1194 static_cast< cppu::OWeakObject
* >( this ) );
1199 if ( rValue
.Value
>>= aNewValue
)
1202 if ( !aNewValue
.isEmpty() )
1204 if ( aNewValue
!= m_aProps
.getTitle() )
1206 // modified title -> modified URL -> exchange !
1207 if ( m_eState
== PERSISTENT
)
1210 aOldTitle
= m_aProps
.getTitle();
1211 m_aProps
.setTitle( aNewValue
);
1213 // property change event will be sent later...
1215 // remember position within sequence of values
1216 // (for error handling).
1222 aRet
[ n
] <<= lang::IllegalArgumentException(
1223 OUString( "Empty Title not allowed!" ),
1224 static_cast< cppu::OWeakObject
* >( this ),
1230 aRet
[ n
] <<= beans::IllegalTypeException(
1231 OUString( "Title Property value has wrong type!" ),
1232 static_cast< cppu::OWeakObject
* >( this ) );
1236 else if ( rValue
.Name
== "Storage" )
1238 ContentType eType
= m_aProps
.getType();
1239 if ( eType
== FOLDER
)
1241 aRet
[ n
] <<= lang::IllegalAccessException(
1242 OUString( "Property is read-only!" ),
1243 static_cast< cppu::OWeakObject
* >( this ) );
1247 // Storage is only supported by folders.
1248 aRet
[ n
] <<= beans::UnknownPropertyException(
1249 OUString( "Storage property only supported by folders" ),
1250 static_cast< cppu::OWeakObject
* >( this ) );
1253 else if ( rValue
.Name
== "DocumentModel" )
1255 ContentType eType
= m_aProps
.getType();
1256 if ( eType
== DOCUMENT
)
1258 aRet
[ n
] <<= lang::IllegalAccessException(
1259 OUString( "Property is read-only!" ),
1260 static_cast< cppu::OWeakObject
* >( this ) );
1264 // Storage is only supported by folders.
1265 aRet
[ n
] <<= beans::UnknownPropertyException(
1266 OUString( "DocumentModel property only supported by "
1268 static_cast< cppu::OWeakObject
* >( this ) );
1273 // Not a Core Property! Maybe it's an Additional Core Property?!
1275 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
1277 xAdditionalPropSet
= getAdditionalPropertySet( false );
1278 bTriedToGetAdditionalPropSet
= true;
1281 if ( xAdditionalPropSet
.is() )
1285 uno::Any aOldValue
= xAdditionalPropSet
->getPropertyValue(
1287 if ( aOldValue
!= rValue
.Value
)
1289 xAdditionalPropSet
->setPropertyValue(
1290 rValue
.Name
, rValue
.Value
);
1292 aEvent
.PropertyName
= rValue
.Name
;
1293 aEvent
.OldValue
= aOldValue
;
1294 aEvent
.NewValue
= rValue
.Value
;
1296 aChanges
.getArray()[ nChanged
] = aEvent
;
1300 catch ( beans::UnknownPropertyException
const & e
)
1304 catch ( lang::WrappedTargetException
const & e
)
1308 catch ( beans::PropertyVetoException
const & e
)
1312 catch ( lang::IllegalArgumentException
const & e
)
1319 aRet
[ n
] <<= uno::Exception(
1320 OUString( "No property set for storing the value!" ),
1321 static_cast< cppu::OWeakObject
* >( this ) );
1328 uno::Reference
< ucb::XContentIdentifier
> xOldId
1330 uno::Reference
< ucb::XContentIdentifier
> xNewId
1331 = makeNewIdentifier( m_aProps
.getTitle() );
1334 if ( exchangeIdentity( xNewId
) )
1336 // Adapt persistent data.
1337 renameData( xOldId
, xNewId
);
1339 // Adapt Additional Core Properties.
1340 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1341 xNewId
->getContentIdentifier(),
1347 m_aProps
.setTitle( aOldTitle
);
1351 aRet
[ nTitlePos
] <<= uno::Exception(
1352 OUString("Exchange failed!"),
1353 static_cast< cppu::OWeakObject
* >( this ) );
1357 if ( !aOldTitle
.isEmpty() )
1359 aEvent
.PropertyName
= "Title";
1360 aEvent
.OldValue
= uno::makeAny( aOldTitle
);
1361 aEvent
.NewValue
= uno::makeAny( m_aProps
.getTitle() );
1363 aChanges
.getArray()[ nChanged
] = aEvent
;
1369 // Save changes, if content was already made persistent.
1370 if ( !bExchange
&& ( m_eState
== PERSISTENT
) )
1372 if ( !storeData( uno::Reference
< io::XInputStream
>(), xEnv
) )
1376 beans::PropertyValue(
1379 uno::makeAny(m_xIdentifier
->
1380 getContentIdentifier()),
1381 beans::PropertyState_DIRECT_VALUE
));
1382 ucbhelper::cancelCommandExecution(
1383 ucb::IOErrorCode_CANT_WRITE
,
1384 uno::Sequence
< uno::Any
>(&aProps
, 1),
1386 OUString( "Cannot store persistent data!" ),
1392 aChanges
.realloc( nChanged
);
1395 notifyPropertiesChange( aChanges
);
1402 uno::Any
Content::open(
1403 const ucb::OpenCommandArgument2
& rArg
,
1404 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1405 throw( uno::Exception
)
1407 if ( rArg
.Mode
== ucb::OpenMode::ALL
||
1408 rArg
.Mode
== ucb::OpenMode::FOLDERS
||
1409 rArg
.Mode
== ucb::OpenMode::DOCUMENTS
)
1412 // open command for a folder content
1415 uno::Reference
< ucb::XDynamicResultSet
> xSet
1416 = new DynamicResultSet( m_xContext
, this, rArg
);
1417 return uno::makeAny( xSet
);
1422 // open command for a document content
1425 if ( ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
1426 ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
) )
1428 // Currently(?) unsupported.
1429 ucbhelper::cancelCommandExecution(
1430 uno::makeAny( ucb::UnsupportedOpenModeException(
1432 static_cast< cppu::OWeakObject
* >( this ),
1433 sal_Int16( rArg
.Mode
) ) ),
1438 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1440 uno::Reference
< io::XActiveDataStreamer
> xDataStreamer(
1441 rArg
.Sink
, uno::UNO_QUERY
);
1442 if ( xDataStreamer
.is() )
1444 // May throw CommandFailedException, DocumentPasswordRequest!
1445 uno::Reference
< io::XStream
> xStream
= getStream( xEnv
);
1446 if ( !xStream
.is() )
1448 // No interaction if we are not persistent!
1451 beans::PropertyValue(
1454 uno::makeAny(m_xIdentifier
->
1455 getContentIdentifier()),
1456 beans::PropertyState_DIRECT_VALUE
));
1457 ucbhelper::cancelCommandExecution(
1458 ucb::IOErrorCode_CANT_READ
,
1459 uno::Sequence
< uno::Any
>(&aProps
, 1),
1460 m_eState
== PERSISTENT
1462 : uno::Reference
< ucb::XCommandEnvironment
>(),
1463 OUString( "Got no data stream!" ),
1469 xDataStreamer
->setStream( xStream
);
1473 uno::Reference
< io::XOutputStream
> xOut( rArg
.Sink
, uno::UNO_QUERY
);
1476 // PUSH: write data into xOut
1478 // May throw CommandFailedException, DocumentPasswordRequest!
1479 uno::Reference
< io::XInputStream
> xIn
= getInputStream( xEnv
);
1482 // No interaction if we are not persistent!
1485 beans::PropertyValue(
1488 uno::makeAny(m_xIdentifier
->
1489 getContentIdentifier()),
1490 beans::PropertyState_DIRECT_VALUE
));
1491 ucbhelper::cancelCommandExecution(
1492 ucb::IOErrorCode_CANT_READ
,
1493 uno::Sequence
< uno::Any
>(&aProps
, 1),
1494 m_eState
== PERSISTENT
1496 : uno::Reference
< ucb::XCommandEnvironment
>(),
1497 OUString("Got no data stream!"),
1504 uno::Sequence
< sal_Int8
> aBuffer
;
1505 sal_Int32 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1509 aBuffer
.realloc( nRead
);
1510 xOut
->writeBytes( aBuffer
);
1511 aBuffer
.realloc( 0 );
1512 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1515 xOut
->closeOutput();
1517 catch ( io::NotConnectedException
const & )
1519 // closeOutput, readSomeBytes, writeBytes
1521 catch ( io::BufferSizeExceededException
const & )
1523 // closeOutput, readSomeBytes, writeBytes
1525 catch ( io::IOException
const & )
1527 // closeOutput, readSomeBytes, writeBytes
1532 uno::Reference
< io::XActiveDataSink
> xDataSink(
1533 rArg
.Sink
, uno::UNO_QUERY
);
1534 if ( xDataSink
.is() )
1536 // PULL: wait for client read
1538 // May throw CommandFailedException, DocumentPasswordRequest!
1539 uno::Reference
< io::XInputStream
> xIn
= getInputStream( xEnv
);
1542 // No interaction if we are not persistent!
1545 beans::PropertyValue(
1548 uno::makeAny(m_xIdentifier
->
1549 getContentIdentifier()),
1550 beans::PropertyState_DIRECT_VALUE
));
1551 ucbhelper::cancelCommandExecution(
1552 ucb::IOErrorCode_CANT_READ
,
1553 uno::Sequence
< uno::Any
>(&aProps
, 1),
1554 m_eState
== PERSISTENT
1557 ucb::XCommandEnvironment
>(),
1558 OUString( "Got no data stream!" ),
1564 xDataSink
->setInputStream( xIn
);
1568 ucbhelper::cancelCommandExecution(
1570 ucb::UnsupportedDataSinkException(
1572 static_cast< cppu::OWeakObject
* >( this ),
1585 void Content::insert( const uno::Reference
< io::XInputStream
>& xData
,
1586 sal_Int32 nNameClashResolve
,
1587 const uno::Reference
<
1588 ucb::XCommandEnvironment
> & xEnv
)
1589 throw( uno::Exception
)
1591 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1593 ContentType eType
= m_aProps
.getType();
1595 OSL_ENSURE( ( eType
== FOLDER
) || ( eType
== STREAM
),
1596 "insert command only supported by streams and folders!" );
1598 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
1600 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
1601 #if OSL_DEBUG_LEVEL > 0
1602 if ( eType
== STREAM
)
1604 Uri
aParentUri( aUri
.getParentUri() );
1605 OSL_ENSURE( !aParentUri
.isDocument(),
1606 "insert command not supported by streams that are direct "
1607 "children of document root!" );
1612 // Check, if all required properties were set.
1613 if ( eType
== FOLDER
)
1617 if ( m_aProps
.getTitle().isEmpty() )
1618 m_aProps
.setTitle( aUri
.getDecodedName() );
1626 ucbhelper::cancelCommandExecution(
1627 uno::makeAny( ucb::MissingInputStreamException(
1629 static_cast< cppu::OWeakObject
* >( this ) ) ),
1636 if ( m_aProps
.getTitle().isEmpty() )
1637 m_aProps
.setTitle( aUri
.getDecodedName() );
1640 OUStringBuffer aNewURL
= aUri
.getParentUri();
1641 aNewURL
.append( m_aProps
.getTitle() );
1642 Uri
aNewUri( aNewURL
.makeStringAndClear() );
1644 // Handle possible name clash...
1645 switch ( nNameClashResolve
)
1648 case ucb::NameClash::ERROR
:
1649 if ( hasData( aNewUri
) )
1651 ucbhelper::cancelCommandExecution(
1652 uno::makeAny( ucb::NameClashException(
1654 static_cast< cppu::OWeakObject
* >( this ),
1655 task::InteractionClassification_ERROR
,
1656 m_aProps
.getTitle() ) ),
1662 // replace (possibly) existing object.
1663 case ucb::NameClash::OVERWRITE
:
1666 // "invent" a new valid title.
1667 case ucb::NameClash::RENAME
:
1668 if ( hasData( aNewUri
) )
1674 OUStringBuffer aNew
= aNewUri
.getUri();
1675 aNew
.appendAscii( "_" );
1676 aNew
.append( OUString::number( ++nTry
) );
1677 aNewUri
.setUri( aNew
.makeStringAndClear() );
1679 while ( hasData( aNewUri
) && ( nTry
< 1000 ) );
1683 ucbhelper::cancelCommandExecution(
1685 ucb::UnsupportedNameClashException(
1686 OUString( "Unable to resolve name clash!" ),
1687 static_cast< cppu::OWeakObject
* >( this ),
1688 nNameClashResolve
) ),
1694 OUStringBuffer aNewTitle
= m_aProps
.getTitle();
1695 aNewTitle
.appendAscii( "_" );
1696 aNewTitle
.append( OUString::number( ++nTry
) );
1697 m_aProps
.setTitle( aNewTitle
.makeStringAndClear() );
1702 case ucb::NameClash::KEEP
: // deprecated
1703 case ucb::NameClash::ASK
:
1705 if ( hasData( aNewUri
) )
1707 ucbhelper::cancelCommandExecution(
1709 ucb::UnsupportedNameClashException(
1711 static_cast< cppu::OWeakObject
* >( this ),
1712 nNameClashResolve
) ),
1719 // Identifier changed?
1720 bool bNewId
= ( aUri
!= aNewUri
);
1725 = new ::ucbhelper::ContentIdentifier( aNewUri
.getUri() );
1728 if ( !storeData( xData
, xEnv
) )
1731 = uno::makeAny(beans::PropertyValue(
1734 uno::makeAny(m_xIdentifier
->
1735 getContentIdentifier()),
1736 beans::PropertyState_DIRECT_VALUE
));
1737 ucbhelper::cancelCommandExecution(
1738 ucb::IOErrorCode_CANT_WRITE
,
1739 uno::Sequence
< uno::Any
>(&aProps
, 1),
1741 OUString("Cannot store persistent data!"),
1746 m_eState
= PERSISTENT
;
1750 //loadData( m_pProvider, m_aUri, m_aProps );
1758 void Content::destroy( bool bDeletePhysical
,
1759 const uno::Reference
<
1760 ucb::XCommandEnvironment
> & xEnv
)
1761 throw( uno::Exception
)
1763 // @@@ take care about bDeletePhysical -> trashcan support
1765 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1767 ContentType eType
= m_aProps
.getType();
1769 OSL_ENSURE( ( eType
== FOLDER
) || ( eType
== STREAM
),
1770 "delete command only supported by streams and folders!" );
1772 uno::Reference
< ucb::XContent
> xThis
= this;
1775 if ( m_eState
!= PERSISTENT
)
1777 ucbhelper::cancelCommandExecution(
1778 uno::makeAny( ucb::UnsupportedCommandException(
1779 OUString( "Not persistent!" ),
1780 static_cast< cppu::OWeakObject
* >( this ) ) ),
1790 if ( eType
== FOLDER
)
1792 // Process instantiated children...
1794 ContentRefList aChildren
;
1795 queryChildren( aChildren
);
1797 ContentRefList::const_iterator it
= aChildren
.begin();
1798 ContentRefList::const_iterator end
= aChildren
.end();
1802 (*it
)->destroy( bDeletePhysical
, xEnv
);
1809 void Content::notifyDocumentClosed()
1811 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1815 // @@@ anything else to reset or such?
1817 // callback follows!
1820 // Propagate destruction to content event listeners
1821 // Remove this from provider's content list.
1826 uno::Reference
< ucb::XContent
>
1827 Content::queryChildContent( const OUString
& rRelativeChildUri
)
1829 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1831 const OUString aMyId
= getIdentifier()->getContentIdentifier();
1832 OUStringBuffer
aBuf( aMyId
);
1833 if ( !aMyId
.endsWith("/") )
1834 aBuf
.appendAscii( "/" );
1835 if ( !rRelativeChildUri
.startsWith("/") )
1836 aBuf
.append( rRelativeChildUri
);
1838 aBuf
.append( rRelativeChildUri
.copy( 1 ) );
1840 uno::Reference
< ucb::XContentIdentifier
> xChildId
1841 = new ::ucbhelper::ContentIdentifier( aBuf
.makeStringAndClear() );
1843 uno::Reference
< ucb::XContent
> xChild
;
1846 xChild
= m_pProvider
->queryContent( xChildId
);
1848 catch ( ucb::IllegalIdentifierException
const & )
1853 OSL_ENSURE( xChild
.is(),
1854 "Content::queryChildContent - unable to create child content!" );
1859 void Content::notifyChildRemoved( const OUString
& rRelativeChildUri
)
1861 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1863 // Ugly! Need to create child content object, just to fill event properly.
1864 uno::Reference
< ucb::XContent
> xChild
1865 = queryChildContent( rRelativeChildUri
);
1869 // callback follows!
1872 // Notify "REMOVED" event.
1873 ucb::ContentEvent
aEvt(
1874 static_cast< cppu::OWeakObject
* >( this ),
1875 ucb::ContentAction::REMOVED
,
1878 notifyContentEvent( aEvt
);
1883 void Content::notifyChildInserted( const OUString
& rRelativeChildUri
)
1885 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1887 // Ugly! Need to create child content object, just to fill event properly.
1888 uno::Reference
< ucb::XContent
> xChild
1889 = queryChildContent( rRelativeChildUri
);
1893 // callback follows!
1896 // Notify "INSERTED" event.
1897 ucb::ContentEvent
aEvt(
1898 static_cast< cppu::OWeakObject
* >( this ),
1899 ucb::ContentAction::INSERTED
,
1902 notifyContentEvent( aEvt
);
1907 void Content::transfer(
1908 const ucb::TransferInfo
& rInfo
,
1909 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1910 throw( uno::Exception
)
1912 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1915 if ( m_eState
!= PERSISTENT
)
1917 ucbhelper::cancelCommandExecution(
1918 uno::makeAny( ucb::UnsupportedCommandException(
1919 OUString( "Not persistent!" ),
1920 static_cast< cppu::OWeakObject
* >( this ) ) ),
1925 // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
1927 if ( ( rInfo
.SourceURL
.getLength() < TDOC_URL_SCHEME_LENGTH
+ 2 ) )
1929 // Invalid length (to short).
1930 ucbhelper::cancelCommandExecution(
1931 uno::makeAny( ucb::InteractiveBadTransferURLException(
1933 static_cast< cppu::OWeakObject
* >( this ) ) ),
1939 = rInfo
.SourceURL
.copy( 0, TDOC_URL_SCHEME_LENGTH
+ 2 )
1940 .toAsciiLowerCase();
1941 if ( aScheme
!= TDOC_URL_SCHEME
":/" )
1944 ucbhelper::cancelCommandExecution(
1945 uno::makeAny( ucb::InteractiveBadTransferURLException(
1947 static_cast< cppu::OWeakObject
* >( this ) ) ),
1952 // Does source URI describe a tdoc folder or stream?
1953 Uri
aSourceUri( rInfo
.SourceURL
);
1954 if ( !aSourceUri
.isValid() )
1956 ucbhelper::cancelCommandExecution(
1957 uno::makeAny( lang::IllegalArgumentException(
1958 OUString( "Invalid source URI! Syntax!" ),
1959 static_cast< cppu::OWeakObject
* >( this ),
1965 if ( aSourceUri
.isRoot() || aSourceUri
.isDocument() )
1967 ucbhelper::cancelCommandExecution(
1968 uno::makeAny( lang::IllegalArgumentException(
1969 OUString( "Invalid source URI! "
1970 "Must describe a folder or stream!" ),
1971 static_cast< cppu::OWeakObject
* >( this ),
1977 // Is source not a parent of me / not me?
1978 OUString aId
= m_xIdentifier
->getContentIdentifier();
1979 sal_Int32 nPos
= aId
.lastIndexOf( '/' );
1980 if ( nPos
!= ( aId
.getLength() - 1 ) )
1982 // No trailing slash found. Append.
1986 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1988 if ( aId
.startsWith( rInfo
.SourceURL
) )
1991 = uno::makeAny(beans::PropertyValue(
1994 uno::makeAny( rInfo
.SourceURL
),
1995 beans::PropertyState_DIRECT_VALUE
));
1996 ucbhelper::cancelCommandExecution(
1997 ucb::IOErrorCode_RECURSIVE
,
1998 uno::Sequence
< uno::Any
>(&aProps
, 1),
2000 OUString( "Target is equal to or is a child of source!" ),
2006 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
2007 if ( m_aProps
.getType() == DOCUMENT
)
2011 uno::Reference
< embed::XStorage
> xStorage
2012 = m_pProvider
->queryStorage(
2013 aSourceUri
.getParentUri(), READ_WRITE_NOCREATE
);
2014 if ( xStorage
.is() )
2018 if ( xStorage
->isStreamElement( aSourceUri
.getDecodedName() ) )
2020 ucbhelper::cancelCommandExecution(
2021 uno::makeAny( lang::IllegalArgumentException(
2022 OUString( "Invalid source URI! "
2023 "Streams cannot be created as "
2024 "children of document root!" ),
2025 static_cast< cppu::OWeakObject
* >(
2033 catch ( container::NoSuchElementException
const & )
2037 catch ( lang::IllegalArgumentException
const & )
2041 catch ( embed::InvalidStorageException
const & )
2049 ucbhelper::cancelCommandExecution(
2050 uno::makeAny( lang::IllegalArgumentException(
2051 OUString( "Invalid source URI! "
2052 "Unabale to determine source type!" ),
2053 static_cast< cppu::OWeakObject
* >( this ),
2065 OUString
aNewName( !rInfo
.NewTitle
.isEmpty()
2067 : aSourceUri
.getDecodedName() );
2069 if ( !copyData( aSourceUri
, aNewName
) )
2073 beans::PropertyValue(
2076 uno::makeAny( rInfo
.SourceURL
),
2077 beans::PropertyState_DIRECT_VALUE
));
2078 ucbhelper::cancelCommandExecution(
2079 ucb::IOErrorCode_CANT_WRITE
,
2080 uno::Sequence
< uno::Any
>(&aProps
, 1),
2082 OUString( "Cannot copy data!" ),
2088 // Copy own and all children's Additional Core Properties.
2091 OUString aTargetUri
= m_xIdentifier
->getContentIdentifier();
2092 if ( ( aTargetUri
.lastIndexOf( '/' ) + 1 ) != aTargetUri
.getLength() )
2095 if ( !rInfo
.NewTitle
.isEmpty() )
2096 aTargetUri
+= ::ucb_impl::urihelper::encodeSegment( rInfo
.NewTitle
);
2098 aTargetUri
+= aSourceUri
.getName();
2100 if ( !copyAdditionalPropertySet(
2101 aSourceUri
.getUri(), aTargetUri
, true ) )
2105 beans::PropertyValue(
2108 uno::makeAny( rInfo
.SourceURL
),
2109 beans::PropertyState_DIRECT_VALUE
));
2110 ucbhelper::cancelCommandExecution(
2111 ucb::IOErrorCode_CANT_WRITE
,
2112 uno::Sequence
< uno::Any
>(&aProps
, 1),
2114 OUString( "Cannot copy additional properties!" ),
2120 // Propagate new content.
2123 rtl::Reference
< Content
> xTarget
;
2126 uno::Reference
< ucb::XContentIdentifier
> xTargetId
2127 = new ::ucbhelper::ContentIdentifier( aTargetUri
);
2129 // Note: The static cast is okay here, because its sure that
2130 // m_xProvider is always the WebDAVContentProvider.
2131 xTarget
= static_cast< Content
* >(
2132 m_pProvider
->queryContent( xTargetId
).get() );
2135 catch ( ucb::IllegalIdentifierException
const & )
2140 if ( !xTarget
.is() )
2143 = uno::makeAny(beans::PropertyValue(
2146 uno::makeAny( aTargetUri
),
2147 beans::PropertyState_DIRECT_VALUE
));
2148 ucbhelper::cancelCommandExecution(
2149 ucb::IOErrorCode_CANT_READ
,
2150 uno::Sequence
< uno::Any
>(&aProps
, 1),
2152 OUString( "Cannot instanciate target object!" ),
2157 // Announce transferred content in its new folder.
2158 xTarget
->inserted();
2161 // Remove source, if requested
2164 if ( rInfo
.MoveData
)
2166 rtl::Reference
< Content
> xSource
;
2169 uno::Reference
< ucb::XContentIdentifier
>
2170 xSourceId
= new ::ucbhelper::ContentIdentifier( rInfo
.SourceURL
);
2172 // Note: The static cast is okay here, because its sure
2173 // that m_xProvider is always the ContentProvider.
2174 xSource
= static_cast< Content
* >(
2175 m_xProvider
->queryContent( xSourceId
).get() );
2177 catch ( ucb::IllegalIdentifierException
const & )
2182 if ( !xSource
.is() )
2185 = uno::makeAny(beans::PropertyValue(
2188 uno::makeAny( rInfo
.SourceURL
),
2189 beans::PropertyState_DIRECT_VALUE
));
2190 ucbhelper::cancelCommandExecution(
2191 ucb::IOErrorCode_CANT_READ
,
2192 uno::Sequence
< uno::Any
>(&aProps
, 1),
2194 OUString( "Cannot instanciate target object!" ),
2199 // Propagate destruction (recursively).
2200 xSource
->destroy( true, xEnv
);
2202 // Remove all persistent data of source and its children.
2203 if ( !xSource
->removeData() )
2207 beans::PropertyValue(
2210 uno::makeAny( rInfo
.SourceURL
),
2211 beans::PropertyState_DIRECT_VALUE
));
2212 ucbhelper::cancelCommandExecution(
2213 ucb::IOErrorCode_CANT_WRITE
,
2214 uno::Sequence
< uno::Any
>(&aProps
, 1),
2216 OUString( "Cannot remove persistent data of source object!" ),
2221 // Remove own and all children's Additional Core Properties.
2222 if ( !xSource
->removeAdditionalPropertySet( true ) )
2226 beans::PropertyValue(
2229 uno::makeAny( rInfo
.SourceURL
),
2230 beans::PropertyState_DIRECT_VALUE
));
2231 ucbhelper::cancelCommandExecution(
2232 ucb::IOErrorCode_CANT_WRITE
,
2233 uno::Sequence
< uno::Any
>(&aProps
, 1),
2235 OUString( "Cannot remove additional properties of source object!" ),
2245 bool Content::hasData( ContentProvider
* pProvider
, const Uri
& rUri
)
2247 if ( rUri
.isRoot() )
2249 return true; // root has no storage
2251 else if ( rUri
.isDocument() )
2253 uno::Reference
< embed::XStorage
> xStorage
2254 = pProvider
->queryStorage( rUri
.getUri(), READ
);
2255 return xStorage
.is();
2261 // Ask parent storage. In case that rUri describes a stream,
2262 // ContentProvider::queryStorage( rUri ) would return null.
2264 uno::Reference
< embed::XStorage
> xStorage
2265 = pProvider
->queryStorage( rUri
.getParentUri(), READ
);
2267 if ( !xStorage
.is() )
2270 uno::Reference
< container::XNameAccess
> xParentNA(
2271 xStorage
, uno::UNO_QUERY
);
2273 OSL_ENSURE( xParentNA
.is(), "Got no css.container.XNameAccess!" );
2275 return xParentNA
->hasByName( rUri
.getDecodedName() );
2281 bool Content::loadData( ContentProvider
* pProvider
,
2283 ContentProperties
& rProps
)
2285 if ( rUri
.isRoot() ) // root has no storage, but can always be created
2288 = ContentProperties(
2289 ROOT
, pProvider
->queryStorageTitle( rUri
.getUri() ) );
2291 else if ( rUri
.isDocument() ) // document must have storage
2293 uno::Reference
< embed::XStorage
> xStorage
2294 = pProvider
->queryStorage( rUri
.getUri(), READ
);
2296 if ( !xStorage
.is() )
2300 = ContentProperties(
2301 DOCUMENT
, pProvider
->queryStorageTitle( rUri
.getUri() ) );
2303 else // stream or folder; stream has no storage; folder has storage
2305 uno::Reference
< embed::XStorage
> xStorage
2306 = pProvider
->queryStorage( rUri
.getParentUri(), READ
);
2308 if ( !xStorage
.is() )
2311 // Check whether exists at all, is stream or folder
2314 // return: true -> folder
2315 // return: false -> stream
2316 // NoSuchElementException -> neither folder nor stream
2318 = xStorage
->isStorageElement( rUri
.getDecodedName() );
2321 = ContentProperties(
2322 bIsFolder
? FOLDER
: STREAM
,
2323 pProvider
->queryStorageTitle( rUri
.getUri() ) );
2325 catch ( container::NoSuchElementException
const & )
2327 // there is no element with such name
2328 //OSL_ENSURE( false, "Caught NoSuchElementException!" );
2331 catch ( lang::IllegalArgumentException
const & )
2333 // an illegal argument is provided
2334 OSL_FAIL( "Caught IllegalArgumentException!" );
2337 catch ( embed::InvalidStorageException
const & )
2339 // this storage is in invalid state for any reason
2340 OSL_FAIL( "Caught InvalidStorageException!" );
2348 bool Content::storeData( const uno::Reference
< io::XInputStream
>& xData
,
2349 const uno::Reference
<
2350 ucb::XCommandEnvironment
>& xEnv
)
2351 throw ( ucb::CommandFailedException
,
2352 task::DocumentPasswordRequest
,
2353 css::uno::RuntimeException
)
2355 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2357 ContentType eType
= m_aProps
.getType();
2358 if ( ( eType
== ROOT
) || ( eType
== DOCUMENT
) )
2360 OSL_FAIL( "storeData not supported by root and documents!" );
2364 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
2366 if ( eType
== FOLDER
)
2368 uno::Reference
< embed::XStorage
> xStorage
2369 = m_pProvider
->queryStorage( aUri
.getUri(), READ_WRITE_CREATE
);
2371 if ( !xStorage
.is() )
2374 uno::Reference
< beans::XPropertySet
> xPropSet(
2375 xStorage
, uno::UNO_QUERY
);
2376 OSL_ENSURE( xPropSet
.is(),
2377 "Content::storeData - Got no XPropertySet interface!" );
2378 if ( !xPropSet
.is() )
2383 // According to MBA, if no mediatype is set, folder and all
2384 // its contents will be lost on save of the document!!!
2385 xPropSet
->setPropertyValue(
2386 OUString( "MediaType" ),
2388 OUString( // @@@ better mediatype
2389 "application/binary" ) ) );
2391 catch ( beans::UnknownPropertyException
const & )
2393 OSL_FAIL( "Property MediaType not supported!" );
2396 catch ( beans::PropertyVetoException
const & )
2398 OSL_FAIL( "Caught PropertyVetoException!" );
2401 catch ( lang::IllegalArgumentException
const & )
2403 OSL_FAIL( "Caught IllegalArgumentException!" );
2406 catch ( lang::WrappedTargetException
const & )
2408 OSL_FAIL( "Caught WrappedTargetException!" );
2412 if ( !commitStorage( xStorage
) )
2415 else if ( eType
== STREAM
)
2419 // Important: Parent storage and output stream must be kept alive until
2420 // changes have been committed!
2421 uno::Reference
< embed::XStorage
> xStorage
2422 = m_pProvider
->queryStorage(
2423 aUri
.getParentUri(), READ_WRITE_CREATE
);
2424 uno::Reference
< io::XOutputStream
> xOut
;
2426 if ( !xStorage
.is() )
2431 // May throw CommandFailedException, DocumentPasswordRequest!
2432 xOut
= getTruncatedOutputStream( xEnv
);
2434 OSL_ENSURE( xOut
.is(), "No target data stream!" );
2438 uno::Sequence
< sal_Int8
> aBuffer
;
2439 sal_Int32 nRead
= xData
->readSomeBytes( aBuffer
, 65536 );
2443 aBuffer
.realloc( nRead
);
2444 xOut
->writeBytes( aBuffer
);
2445 aBuffer
.realloc( 0 );
2446 nRead
= xData
->readSomeBytes( aBuffer
, 65536 );
2449 closeOutputStream( xOut
);
2451 catch ( io::NotConnectedException
const & )
2453 // readSomeBytes, writeBytes
2454 OSL_FAIL( "Caught NotConnectedException!" );
2455 closeOutputStream( xOut
);
2458 catch ( io::BufferSizeExceededException
const & )
2460 // readSomeBytes, writeBytes
2461 OSL_FAIL( "Caught BufferSizeExceededException!" );
2462 closeOutputStream( xOut
);
2465 catch ( io::IOException
const & )
2467 // readSomeBytes, writeBytes
2468 OSL_FAIL( "Caught IOException!" );
2469 closeOutputStream( xOut
);
2474 closeOutputStream( xOut
);
2480 if ( !commitStorage( xStorage
) )
2485 OSL_FAIL( "Unknown content type!" );
2492 bool Content::renameData(
2493 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
2494 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2496 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2498 ContentType eType
= m_aProps
.getType();
2499 if ( ( eType
== ROOT
) || ( eType
== DOCUMENT
) )
2501 OSL_FAIL( "renameData not supported by root and documents!" );
2505 Uri
aOldUri( xOldId
->getContentIdentifier() );
2506 uno::Reference
< embed::XStorage
> xStorage
2507 = m_pProvider
->queryStorage(
2508 aOldUri
.getParentUri(), READ_WRITE_NOCREATE
);
2510 if ( !xStorage
.is() )
2515 Uri
aNewUri( xNewId
->getContentIdentifier() );
2516 xStorage
->renameElement(
2517 aOldUri
.getDecodedName(), aNewUri
.getDecodedName() );
2519 catch ( embed::InvalidStorageException
const & )
2521 // this storage is in invalid state for eny reason
2522 OSL_FAIL( "Caught InvalidStorageException!" );
2525 catch ( lang::IllegalArgumentException
const & )
2527 // an illegal argument is provided
2528 OSL_FAIL( "Caught IllegalArgumentException!" );
2531 catch ( container::NoSuchElementException
const & )
2533 // there is no element with old name in this storage
2534 OSL_FAIL( "Caught NoSuchElementException!" );
2537 catch ( container::ElementExistException
const & )
2539 // an element with new name already exists in this storage
2540 OSL_FAIL( "Caught ElementExistException!" );
2543 catch ( io::IOException
const & )
2545 // in case of io errors during renaming
2546 OSL_FAIL( "Caught IOException!" );
2549 catch ( embed::StorageWrappedTargetException
const & )
2551 // wraps other exceptions
2552 OSL_FAIL( "Caught StorageWrappedTargetException!" );
2556 return commitStorage( xStorage
);
2560 bool Content::removeData()
2562 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2564 ContentType eType
= m_aProps
.getType();
2565 if ( ( eType
== ROOT
) || ( eType
== DOCUMENT
) )
2567 OSL_FAIL( "removeData not supported by root and documents!" );
2571 Uri
aUri( m_xIdentifier
->getContentIdentifier() );
2572 uno::Reference
< embed::XStorage
> xStorage
2573 = m_pProvider
->queryStorage(
2574 aUri
.getParentUri(), READ_WRITE_NOCREATE
);
2576 if ( !xStorage
.is() )
2581 xStorage
->removeElement( aUri
.getDecodedName() );
2583 catch ( embed::InvalidStorageException
const & )
2585 // this storage is in invalid state for eny reason
2586 OSL_FAIL( "Caught InvalidStorageException!" );
2589 catch ( lang::IllegalArgumentException
const & )
2591 // an illegal argument is provided
2592 OSL_FAIL( "Caught IllegalArgumentException!" );
2595 catch ( container::NoSuchElementException
const & )
2597 // there is no element with this name in this storage
2598 OSL_FAIL( "Caught NoSuchElementException!" );
2601 catch ( io::IOException
const & )
2603 // in case of io errors during renaming
2604 OSL_FAIL( "Caught IOException!" );
2607 catch ( embed::StorageWrappedTargetException
const & )
2609 // wraps other exceptions
2610 OSL_FAIL( "Caught StorageWrappedTargetException!" );
2614 return commitStorage( xStorage
);
2618 bool Content::copyData( const Uri
& rSourceUri
, const OUString
& rNewName
)
2620 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2622 ContentType eType
= m_aProps
.getType();
2623 if ( ( eType
== ROOT
) || ( eType
== STREAM
) )
2625 OSL_FAIL( "copyData not supported by root and streams!" );
2629 Uri
aDestUri( m_xIdentifier
->getContentIdentifier() );
2630 uno::Reference
< embed::XStorage
> xDestStorage
2631 = m_pProvider
->queryStorage( aDestUri
.getUri(), READ_WRITE_NOCREATE
);
2633 if ( !xDestStorage
.is() )
2636 uno::Reference
< embed::XStorage
> xSourceStorage
2637 = m_pProvider
->queryStorage( rSourceUri
.getParentUri(), READ
);
2639 if ( !xSourceStorage
.is() )
2644 xSourceStorage
->copyElementTo( rSourceUri
.getDecodedName(),
2648 catch ( embed::InvalidStorageException
const & )
2650 // this storage is in invalid state for eny reason
2651 OSL_FAIL( "Caught InvalidStorageException!" );
2654 catch ( lang::IllegalArgumentException
const & )
2656 // an illegal argument is provided
2657 OSL_FAIL( "Caught IllegalArgumentException!" );
2660 catch ( container::NoSuchElementException
const & )
2662 // there is no element with this name in this storage
2663 OSL_FAIL( "Caught NoSuchElementException!" );
2666 catch ( container::ElementExistException
const & )
2668 // there is no element with this name in this storage
2669 OSL_FAIL( "Caught ElementExistException!" );
2672 catch ( io::IOException
const & )
2674 // in case of io errors during renaming
2675 OSL_FAIL( "Caught IOException!" );
2678 catch ( embed::StorageWrappedTargetException
const & )
2680 // wraps other exceptions
2681 OSL_FAIL( "Caught StorageWrappedTargetException!" );
2685 return commitStorage( xDestStorage
);
2690 bool Content::commitStorage( const uno::Reference
< embed::XStorage
> & xStorage
)
2693 uno::Reference
< embed::XTransactedObject
> xTO( xStorage
, uno::UNO_QUERY
);
2695 OSL_ENSURE( xTO
.is(),
2696 "Required interface css.embed.XTransactedObject missing!" );
2701 catch ( io::IOException
const & )
2703 OSL_FAIL( "Caught IOException!" );
2706 catch ( lang::WrappedTargetException
const & )
2708 OSL_FAIL( "Caught WrappedTargetException!" );
2717 bool Content::closeOutputStream(
2718 const uno::Reference
< io::XOutputStream
> & xOut
)
2724 xOut
->closeOutput();
2727 catch ( io::NotConnectedException
const & )
2729 OSL_FAIL( "Caught NotConnectedException!" );
2731 catch ( io::BufferSizeExceededException
const & )
2733 OSL_FAIL( "Caught BufferSizeExceededException!" );
2735 catch ( io::IOException
const & )
2737 OSL_FAIL( "Caught IOException!" );
2744 static OUString
obtainPassword(
2745 const OUString
& rName
,
2746 task::PasswordRequestMode eMode
,
2747 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
2748 throw ( ucb::CommandFailedException
,
2749 task::DocumentPasswordRequest
)
2751 rtl::Reference
< DocumentPasswordRequest
> xRequest
2752 = new DocumentPasswordRequest( eMode
, rName
);
2756 uno::Reference
< task::XInteractionHandler
> xIH
2757 = xEnv
->getInteractionHandler();
2760 xIH
->handle( xRequest
.get() );
2762 rtl::Reference
< ucbhelper::InteractionContinuation
> xSelection
2763 = xRequest
->getSelection();
2765 if ( xSelection
.is() )
2767 // Handler handled the request.
2768 uno::Reference
< task::XInteractionAbort
> xAbort(
2769 xSelection
.get(), uno::UNO_QUERY
);
2772 throw ucb::CommandFailedException(
2773 OUString( "Abort requested by Interaction Handler." ),
2774 uno::Reference
< uno::XInterface
>(),
2775 xRequest
->getRequest() );
2778 uno::Reference
< task::XInteractionPassword
> xPassword(
2779 xSelection
.get(), uno::UNO_QUERY
);
2780 if ( xPassword
.is() )
2782 return xPassword
->getPassword();
2785 // Unknown selection. Should never happen.
2786 throw ucb::CommandFailedException(
2787 OUString( "Interaction Handler selected unknown continuation!" ),
2788 uno::Reference
< uno::XInterface
>(),
2789 xRequest
->getRequest() );
2794 // No IH or IH did not handle exception.
2795 task::DocumentPasswordRequest aRequest
;
2796 xRequest
->getRequest() >>= aRequest
;
2801 uno::Reference
< io::XInputStream
> Content::getInputStream(
2802 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
2803 throw ( ucb::CommandFailedException
,
2804 task::DocumentPasswordRequest
,
2805 uno::RuntimeException
)
2809 bool bPasswordRequested
= false;
2812 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2814 OSL_ENSURE( m_aProps
.getType() == STREAM
,
2815 "Content::getInputStream - content is no stream!" );
2817 aUri
= Uri( m_xIdentifier
->getContentIdentifier() ).getUri();
2824 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2825 return uno::Reference
< io::XInputStream
>(
2826 m_pProvider
->queryInputStream( aUri
, aPassword
) );
2828 catch ( packages::WrongPasswordException
const & )
2830 // Obtain (new) password.
2832 = obtainPassword( aUri
, /* @@@ find better title */
2834 ? task::PasswordRequestMode_PASSWORD_REENTER
2835 : task::PasswordRequestMode_PASSWORD_ENTER
,
2837 bPasswordRequested
= true;
2843 static uno::Reference
< io::XOutputStream
> lcl_getTruncatedOutputStream(
2844 const OUString
& rUri
,
2845 ContentProvider
* pProvider
,
2846 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
2847 throw ( ucb::CommandFailedException
,
2848 task::DocumentPasswordRequest
,
2849 uno::RuntimeException
)
2852 bool bPasswordRequested
= false;
2857 return uno::Reference
< io::XOutputStream
>(
2858 pProvider
->queryOutputStream(
2859 rUri
, aPassword
, true /* truncate */ ) );
2861 catch ( packages::WrongPasswordException
const & )
2863 // Obtain (new) password.
2865 = obtainPassword( rUri
, /* @@@ find better title */
2867 ? task::PasswordRequestMode_PASSWORD_REENTER
2868 : task::PasswordRequestMode_PASSWORD_ENTER
,
2870 bPasswordRequested
= true;
2876 uno::Reference
< io::XOutputStream
> Content::getTruncatedOutputStream(
2877 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
2878 throw ( ucb::CommandFailedException
,
2879 task::DocumentPasswordRequest
,
2880 css::uno::RuntimeException
)
2882 OSL_ENSURE( m_aProps
.getType() == STREAM
,
2883 "Content::getTruncatedOutputStream - content is no stream!" );
2885 return lcl_getTruncatedOutputStream(
2886 Uri( m_xIdentifier
->getContentIdentifier() ).getUri(),
2892 uno::Reference
< io::XStream
> Content::getStream(
2893 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
2894 throw ( ucb::CommandFailedException
,
2895 task::DocumentPasswordRequest
,
2896 uno::RuntimeException
)
2898 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2900 OSL_ENSURE( m_aProps
.getType() == STREAM
,
2901 "Content::getStream - content is no stream!" );
2903 OUString
aUri( Uri( m_xIdentifier
->getContentIdentifier() ).getUri() );
2905 bool bPasswordRequested
= false;
2910 return uno::Reference
< io::XStream
>(
2911 m_pProvider
->queryStream(
2912 aUri
, aPassword
, false /* no truncate */ ) );
2914 catch ( packages::WrongPasswordException
const & )
2916 // Obtain (new) password.
2918 = obtainPassword( aUri
, /* @@@ find better title */
2920 ? task::PasswordRequestMode_PASSWORD_REENTER
2921 : task::PasswordRequestMode_PASSWORD_ENTER
,
2923 bPasswordRequested
= true;
2931 // ContentProperties Implementation.
2936 uno::Sequence
< ucb::ContentInfo
>
2937 ContentProperties::getCreatableContentsInfo() const
2939 if ( isContentCreator() )
2941 uno::Sequence
< beans::Property
> aProps( 1 );
2942 aProps
.getArray()[ 0 ] = beans::Property(
2945 cppu::UnoType
<OUString
>::get(),
2946 beans::PropertyAttribute::BOUND
);
2948 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
2949 if ( getType() == DOCUMENT
)
2951 // streams cannot be created as direct children of document root
2952 uno::Sequence
< ucb::ContentInfo
> aSeq( 1 );
2955 aSeq
.getArray()[ 0 ].Type
= TDOC_FOLDER_CONTENT_TYPE
;
2956 aSeq
.getArray()[ 0 ].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
2957 aSeq
.getArray()[ 0 ].Properties
= aProps
;
2964 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
2967 aSeq
.getArray()[ 0 ].Type
= TDOC_FOLDER_CONTENT_TYPE
;
2968 aSeq
.getArray()[ 0 ].Attributes
2969 = ucb::ContentInfoAttribute::KIND_FOLDER
;
2970 aSeq
.getArray()[ 0 ].Properties
= aProps
;
2973 aSeq
.getArray()[ 1 ].Type
= TDOC_STREAM_CONTENT_TYPE
;
2974 aSeq
.getArray()[ 1 ].Attributes
2975 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
2976 | ucb::ContentInfoAttribute::KIND_DOCUMENT
;
2977 aSeq
.getArray()[ 1 ].Properties
= aProps
;
2980 #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
2986 OSL_FAIL( "getCreatableContentsInfo called on non-contentcreator "
2989 return uno::Sequence
< ucb::ContentInfo
>( 0 );
2994 bool ContentProperties::isContentCreator() const
2996 return ( getType() == FOLDER
) || ( getType() == DOCUMENT
);
2999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */