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 **************************************************************************
24 *************************************************************************/
25 #include <osl/diagnose.h>
27 #include "osl/doublecheckedlocking.h"
28 #include <rtl/ustring.h>
29 #include <rtl/ustring.hxx>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/beans/PropertyState.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/XPropertyAccess.hpp>
34 #include <com/sun/star/container/XEnumerationAccess.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/lang/IllegalAccessException.hpp>
42 #include <com/sun/star/sdbc/XRow.hpp>
43 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
44 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
45 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
46 #include <com/sun/star/ucb/MissingInputStreamException.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/UnsupportedDataSinkException.hpp>
53 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
54 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
55 #include <com/sun/star/ucb/XCommandInfo.hpp>
56 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
57 #include <com/sun/star/util/XChangesBatch.hpp>
58 #include <com/sun/star/uno/Any.hxx>
59 #include <com/sun/star/uno/Sequence.hxx>
60 #include <comphelper/processfactory.hxx>
61 #include <ucbhelper/contentidentifier.hxx>
62 #include <ucbhelper/propertyvalueset.hxx>
63 #include <ucbhelper/cancelcommandexecution.hxx>
64 #include "pkgcontent.hxx"
65 #include "pkgprovider.hxx"
66 #include "pkgresultset.hxx"
68 #include "../inc/urihelper.hxx"
70 using namespace com::sun::star
;
71 using namespace package_ucp
;
73 #define NONE_MODIFIED sal_uInt32( 0x00 )
74 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
75 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
76 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
77 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
79 //=========================================================================
80 //=========================================================================
82 // ContentProperties Implementation.
84 //=========================================================================
85 //=========================================================================
87 ContentProperties::ContentProperties( const OUString
& rContentType
)
88 : aContentType( rContentType
),
90 bCompressed( sal_True
),
91 bEncrypted( sal_False
),
92 bHasEncryptedEntries( sal_False
)
94 bIsFolder
= rContentType
== PACKAGE_FOLDER_CONTENT_TYPE
|| rContentType
== PACKAGE_ZIP_FOLDER_CONTENT_TYPE
;
95 bIsDocument
= !bIsFolder
;
97 OSL_ENSURE( bIsFolder
|| rContentType
== PACKAGE_STREAM_CONTENT_TYPE
|| rContentType
== PACKAGE_ZIP_STREAM_CONTENT_TYPE
,
98 "ContentProperties::ContentProperties - Unknown type!" );
101 //=========================================================================
103 uno::Sequence
< ucb::ContentInfo
>
104 ContentProperties::getCreatableContentsInfo( PackageUri
const & rUri
) const
108 uno::Sequence
< beans::Property
> aProps( 1 );
109 aProps
.getArray()[ 0 ] = beans::Property(
112 getCppuType( static_cast< const OUString
* >( 0 ) ),
113 beans::PropertyAttribute::BOUND
);
115 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
118 aSeq
.getArray()[ 0 ].Type
119 = Content::getContentType( rUri
.getScheme(), sal_True
);
120 aSeq
.getArray()[ 0 ].Attributes
121 = ucb::ContentInfoAttribute::KIND_FOLDER
;
122 aSeq
.getArray()[ 0 ].Properties
= aProps
;
125 aSeq
.getArray()[ 1 ].Type
126 = Content::getContentType( rUri
.getScheme(), sal_False
);
127 aSeq
.getArray()[ 1 ].Attributes
128 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
129 | ucb::ContentInfoAttribute::KIND_DOCUMENT
;
130 aSeq
.getArray()[ 1 ].Properties
= aProps
;
136 return uno::Sequence
< ucb::ContentInfo
>( 0 );
140 //=========================================================================
141 //=========================================================================
143 // Content Implementation.
145 //=========================================================================
146 //=========================================================================
148 // static ( "virtual" ctor )
149 Content
* Content::create(
150 const uno::Reference
< uno::XComponentContext
>& rxContext
,
151 ContentProvider
* pProvider
,
152 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
154 OUString aURL
= Identifier
->getContentIdentifier();
155 PackageUri
aURI( aURL
);
156 ContentProperties aProps
;
157 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
159 if ( loadData( pProvider
, aURI
, aProps
, xPackage
) )
163 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
164 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
166 // Client explicitly requested a folder!
167 if ( !aProps
.bIsFolder
)
171 uno::Reference
< ucb::XContentIdentifier
> xId
172 = new ::ucbhelper::ContentIdentifier( aURI
.getUri() );
173 return new Content( rxContext
, pProvider
, xId
, xPackage
, aURI
, aProps
);
177 // resource doesn't exist
179 sal_Bool bFolder
= sal_False
;
181 // Guess type according to URI.
182 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
183 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
186 uno::Reference
< ucb::XContentIdentifier
> xId
187 = new ::ucbhelper::ContentIdentifier( aURI
.getUri() );
189 ucb::ContentInfo aInfo
;
190 if ( bFolder
|| aURI
.isRootFolder() )
191 aInfo
.Type
= getContentType( aURI
.getScheme(), sal_True
);
193 aInfo
.Type
= getContentType( aURI
.getScheme(), sal_False
);
195 return new Content( rxContext
, pProvider
, xId
, xPackage
, aURI
, aInfo
);
199 //=========================================================================
200 // static ( "virtual" ctor )
201 Content
* Content::create(
202 const uno::Reference
< uno::XComponentContext
>& rxContext
,
203 ContentProvider
* pProvider
,
204 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
205 const ucb::ContentInfo
& Info
)
207 if ( Info
.Type
.isEmpty() )
210 PackageUri
aURI( Identifier
->getContentIdentifier() );
212 if ( !Info
.Type
.equalsIgnoreAsciiCase(
213 getContentType( aURI
.getScheme(), sal_True
) ) &&
214 !Info
.Type
.equalsIgnoreAsciiCase(
215 getContentType( aURI
.getScheme(), sal_False
) ) )
218 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
220 xPackage
= pProvider
->createPackage( aURI
.getPackage(), aURI
.getParam() );
222 uno::Reference
< ucb::XContentIdentifier
> xId
223 = new ::ucbhelper::ContentIdentifier( aURI
.getUri() );
224 return new Content( rxContext
, pProvider
, xId
, xPackage
, aURI
, Info
);
227 //=========================================================================
229 OUString
Content::getContentType(
230 const OUString
& aScheme
, sal_Bool bFolder
)
232 return ( OUString("application/")
235 ? OUString("-folder")
236 : OUString("-stream") ) );
239 //=========================================================================
241 const uno::Reference
< uno::XComponentContext
>& rxContext
,
242 ContentProvider
* pProvider
,
243 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
244 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
245 const PackageUri
& rUri
,
246 const ContentProperties
& rProps
)
247 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
250 m_eState( PERSISTENT
),
251 m_xPackage( Package
),
252 m_pProvider( pProvider
),
253 m_nModifiedProps( NONE_MODIFIED
)
257 //=========================================================================
259 const uno::Reference
< uno::XComponentContext
>& rxContext
,
260 ContentProvider
* pProvider
,
261 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
262 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
263 const PackageUri
& rUri
,
264 const ucb::ContentInfo
& Info
)
265 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
267 m_aProps( Info
.Type
),
268 m_eState( TRANSIENT
),
269 m_xPackage( Package
),
270 m_pProvider( pProvider
),
271 m_nModifiedProps( NONE_MODIFIED
)
275 //=========================================================================
281 //=========================================================================
283 // XInterface methods.
285 //=========================================================================
288 void SAL_CALL
Content::acquire()
291 ContentImplHelper::acquire();
294 //=========================================================================
296 void SAL_CALL
Content::release()
299 ContentImplHelper::release();
302 //=========================================================================
304 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
)
305 throw ( uno::RuntimeException
)
310 aRet
= cppu::queryInterface(
311 rType
, static_cast< ucb::XContentCreator
* >( this ) );
313 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface( rType
);
316 //=========================================================================
318 // XTypeProvider methods.
320 //=========================================================================
322 XTYPEPROVIDER_COMMON_IMPL( Content
);
324 //=========================================================================
326 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
327 throw( uno::RuntimeException
)
329 cppu::OTypeCollection
* pCollection
= 0;
333 static cppu::OTypeCollection
* pFolderTypes
= 0;
335 pCollection
= pFolderTypes
;
338 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
340 pCollection
= pFolderTypes
;
343 static cppu::OTypeCollection
aCollection(
344 CPPU_TYPE_REF( lang::XTypeProvider
),
345 CPPU_TYPE_REF( lang::XServiceInfo
),
346 CPPU_TYPE_REF( lang::XComponent
),
347 CPPU_TYPE_REF( ucb::XContent
),
348 CPPU_TYPE_REF( ucb::XCommandProcessor
),
349 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
350 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
351 CPPU_TYPE_REF( beans::XPropertyContainer
),
352 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
353 CPPU_TYPE_REF( container::XChild
),
354 CPPU_TYPE_REF( ucb::XContentCreator
) ); // !!
355 pCollection
= &aCollection
;
356 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
357 pFolderTypes
= pCollection
;
361 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
366 static cppu::OTypeCollection
* pDocumentTypes
= 0;
368 pCollection
= pDocumentTypes
;
371 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
373 pCollection
= pDocumentTypes
;
376 static cppu::OTypeCollection
aCollection(
377 CPPU_TYPE_REF( lang::XTypeProvider
),
378 CPPU_TYPE_REF( lang::XServiceInfo
),
379 CPPU_TYPE_REF( lang::XComponent
),
380 CPPU_TYPE_REF( ucb::XContent
),
381 CPPU_TYPE_REF( ucb::XCommandProcessor
),
382 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
383 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
384 CPPU_TYPE_REF( beans::XPropertyContainer
),
385 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
386 CPPU_TYPE_REF( container::XChild
) );
387 pCollection
= &aCollection
;
388 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
389 pDocumentTypes
= pCollection
;
393 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
397 return (*pCollection
).getTypes();
400 //=========================================================================
402 // XServiceInfo methods.
404 //=========================================================================
407 OUString SAL_CALL
Content::getImplementationName()
408 throw( uno::RuntimeException
)
410 return OUString( "com.sun.star.comp.ucb.PackageContent" );
413 //=========================================================================
415 uno::Sequence
< OUString
> SAL_CALL
Content::getSupportedServiceNames()
416 throw( uno::RuntimeException
)
418 uno::Sequence
< OUString
> aSNS( 1 );
420 aSNS
.getArray()[ 0 ] = OUString( PACKAGE_FOLDER_CONTENT_SERVICE_NAME
);
422 aSNS
.getArray()[ 0 ] = OUString( PACKAGE_STREAM_CONTENT_SERVICE_NAME
);
427 //=========================================================================
431 //=========================================================================
434 OUString SAL_CALL
Content::getContentType()
435 throw( uno::RuntimeException
)
437 return m_aProps
.aContentType
;
440 //=========================================================================
442 // XCommandProcessor methods.
444 //=========================================================================
447 uno::Any SAL_CALL
Content::execute(
448 const ucb::Command
& aCommand
,
449 sal_Int32
/*CommandId*/,
450 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
451 throw( uno::Exception
,
452 ucb::CommandAbortedException
,
453 uno::RuntimeException
)
457 if ( aCommand
.Name
== "getPropertyValues" )
459 //////////////////////////////////////////////////////////////////
461 //////////////////////////////////////////////////////////////////
463 uno::Sequence
< beans::Property
> Properties
;
464 if ( !( aCommand
.Argument
>>= Properties
) )
466 ucbhelper::cancelCommandExecution(
467 uno::makeAny( lang::IllegalArgumentException(
468 OUString( "Wrong argument type!" ),
469 static_cast< cppu::OWeakObject
* >( this ),
475 aRet
<<= getPropertyValues( Properties
);
477 else if ( aCommand
.Name
== "setPropertyValues" )
479 //////////////////////////////////////////////////////////////////
481 //////////////////////////////////////////////////////////////////
483 uno::Sequence
< beans::PropertyValue
> aProperties
;
484 if ( !( aCommand
.Argument
>>= aProperties
) )
486 ucbhelper::cancelCommandExecution(
487 uno::makeAny( lang::IllegalArgumentException(
488 OUString( "Wrong argument type!" ),
489 static_cast< cppu::OWeakObject
* >( this ),
495 if ( !aProperties
.getLength() )
497 ucbhelper::cancelCommandExecution(
498 uno::makeAny( lang::IllegalArgumentException(
499 OUString( "No properties!" ),
500 static_cast< cppu::OWeakObject
* >( this ),
506 aRet
<<= setPropertyValues( aProperties
, Environment
);
508 else if ( aCommand
.Name
== "getPropertySetInfo" )
510 //////////////////////////////////////////////////////////////////
511 // getPropertySetInfo
512 //////////////////////////////////////////////////////////////////
514 // Note: Implemented by base class.
515 aRet
<<= getPropertySetInfo( Environment
);
517 else if ( aCommand
.Name
== "getCommandInfo" )
519 //////////////////////////////////////////////////////////////////
521 //////////////////////////////////////////////////////////////////
523 // Note: Implemented by base class.
524 aRet
<<= getCommandInfo( Environment
);
526 else if ( aCommand
.Name
== "open" )
528 //////////////////////////////////////////////////////////////////
530 //////////////////////////////////////////////////////////////////
532 ucb::OpenCommandArgument2 aOpenCommand
;
533 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
535 ucbhelper::cancelCommandExecution(
536 uno::makeAny( lang::IllegalArgumentException(
537 OUString( "Wrong argument type!" ),
538 static_cast< cppu::OWeakObject
* >( this ),
544 aRet
= open( aOpenCommand
, Environment
);
546 else if ( !m_aUri
.isRootFolder() && aCommand
.Name
== "insert" )
548 //////////////////////////////////////////////////////////////////
550 //////////////////////////////////////////////////////////////////
552 ucb::InsertCommandArgument aArg
;
553 if ( !( aCommand
.Argument
>>= aArg
) )
555 ucbhelper::cancelCommandExecution(
556 uno::makeAny( lang::IllegalArgumentException(
557 OUString( "Wrong argument type!" ),
558 static_cast< cppu::OWeakObject
* >( this ),
564 sal_Int32 nNameClash
= aArg
.ReplaceExisting
565 ? ucb::NameClash::OVERWRITE
566 : ucb::NameClash::ERROR
;
567 insert( aArg
.Data
, nNameClash
, Environment
);
569 else if ( !m_aUri
.isRootFolder() && aCommand
.Name
== "delete" )
571 //////////////////////////////////////////////////////////////////
573 //////////////////////////////////////////////////////////////////
575 sal_Bool bDeletePhysical
= sal_False
;
576 aCommand
.Argument
>>= bDeletePhysical
;
577 destroy( bDeletePhysical
, Environment
);
579 // Remove own and all children's persistent data.
584 beans::PropertyValue(
587 uno::makeAny(m_xIdentifier
->
588 getContentIdentifier()),
589 beans::PropertyState_DIRECT_VALUE
));
590 ucbhelper::cancelCommandExecution(
591 ucb::IOErrorCode_CANT_WRITE
,
592 uno::Sequence
< uno::Any
>(&aProps
, 1),
594 OUString( "Cannot remove persistent data!" ),
599 // Remove own and all children's Additional Core Properties.
600 removeAdditionalPropertySet( sal_True
);
602 else if ( aCommand
.Name
== "transfer" )
604 //////////////////////////////////////////////////////////////////
606 // ( Not available at stream objects )
607 //////////////////////////////////////////////////////////////////
609 ucb::TransferInfo aInfo
;
610 if ( !( aCommand
.Argument
>>= aInfo
) )
612 ucbhelper::cancelCommandExecution(
613 uno::makeAny( lang::IllegalArgumentException(
614 OUString( "Wrong argument type!" ),
615 static_cast< cppu::OWeakObject
* >( this ),
621 transfer( aInfo
, Environment
);
623 else if ( aCommand
.Name
== "createNewContent" && isFolder() )
625 //////////////////////////////////////////////////////////////////
627 // ( Not available at stream objects )
628 //////////////////////////////////////////////////////////////////
630 ucb::ContentInfo aInfo
;
631 if ( !( aCommand
.Argument
>>= aInfo
) )
633 OSL_FAIL( "Wrong argument type!" );
634 ucbhelper::cancelCommandExecution(
635 uno::makeAny( lang::IllegalArgumentException(
636 OUString( "Wrong argument type!" ),
637 static_cast< cppu::OWeakObject
* >( this ),
643 aRet
<<= createNewContent( aInfo
);
645 else if ( aCommand
.Name
== "flush" )
647 //////////////////////////////////////////////////////////////////
649 // ( Not available at stream objects )
650 //////////////////////////////////////////////////////////////////
656 beans::PropertyValue(
659 uno::makeAny(m_xIdentifier
->
660 getContentIdentifier()),
661 beans::PropertyState_DIRECT_VALUE
));
662 ucbhelper::cancelCommandExecution(
663 ucb::IOErrorCode_CANT_WRITE
,
664 uno::Sequence
< uno::Any
>(&aProps
, 1),
666 OUString( "Cannot write file to disk!" ),
673 //////////////////////////////////////////////////////////////////
674 // Unsupported command
675 //////////////////////////////////////////////////////////////////
677 ucbhelper::cancelCommandExecution(
678 uno::makeAny( ucb::UnsupportedCommandException(
680 static_cast< cppu::OWeakObject
* >( this ) ) ),
688 //=========================================================================
690 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
691 throw( uno::RuntimeException
)
693 // @@@ Implement logic to abort running commands, if this makes
694 // sense for your content.
697 //=========================================================================
699 // XContentCreator methods.
701 //=========================================================================
704 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
705 Content::queryCreatableContentsInfo()
706 throw( uno::RuntimeException
)
708 return m_aProps
.getCreatableContentsInfo( m_aUri
);
711 //=========================================================================
713 uno::Reference
< ucb::XContent
> SAL_CALL
714 Content::createNewContent( const ucb::ContentInfo
& Info
)
715 throw( uno::RuntimeException
)
719 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
721 if ( Info
.Type
.isEmpty() )
722 return uno::Reference
< ucb::XContent
>();
724 if ( !Info
.Type
.equalsIgnoreAsciiCase(
725 getContentType( m_aUri
.getScheme(), sal_True
) ) &&
726 !Info
.Type
.equalsIgnoreAsciiCase(
727 getContentType( m_aUri
.getScheme(), sal_False
) ) )
728 return uno::Reference
< ucb::XContent
>();
730 OUString aURL
= m_aUri
.getUri();
731 aURL
+= OUString("/");
733 if ( Info
.Type
.equalsIgnoreAsciiCase(
734 getContentType( m_aUri
.getScheme(), sal_True
) ) )
735 aURL
+= OUString("New_Folder");
737 aURL
+= OUString("New_Stream");
739 uno::Reference
< ucb::XContentIdentifier
> xId(
740 new ::ucbhelper::ContentIdentifier( aURL
) );
742 return create( m_xContext
, m_pProvider
, xId
, Info
);
746 OSL_FAIL( "createNewContent called on non-folder object!" );
747 return uno::Reference
< ucb::XContent
>();
751 //=========================================================================
753 // Non-interface methods.
755 //=========================================================================
758 OUString
Content::getParentURL()
760 return m_aUri
.getParentUri();
763 //=========================================================================
765 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
766 const uno::Reference
< uno::XComponentContext
>& rxContext
,
767 const uno::Sequence
< beans::Property
>& rProperties
,
768 ContentProvider
* pProvider
,
769 const OUString
& rContentId
)
771 ContentProperties aData
;
772 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
773 if ( loadData( pProvider
, PackageUri( rContentId
), aData
, xPackage
) )
775 return getPropertyValues( rxContext
,
779 ::ucbhelper::ContentProviderImplHelper
>(
785 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
786 = new ::ucbhelper::PropertyValueSet( rxContext
);
788 sal_Int32 nCount
= rProperties
.getLength();
791 const beans::Property
* pProps
= rProperties
.getConstArray();
792 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
793 xRow
->appendVoid( pProps
[ n
] );
796 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
800 //=========================================================================
802 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
803 const uno::Reference
< uno::XComponentContext
>& rxContext
,
804 const uno::Sequence
< beans::Property
>& rProperties
,
805 const ContentProperties
& rData
,
806 const rtl::Reference
< ::ucbhelper::ContentProviderImplHelper
>&
808 const OUString
& rContentId
)
810 // Note: Empty sequence means "get values of all supported properties".
812 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
813 = new ::ucbhelper::PropertyValueSet( rxContext
);
815 sal_Int32 nCount
= rProperties
.getLength();
818 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
819 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
821 const beans::Property
* pProps
= rProperties
.getConstArray();
822 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
824 const beans::Property
& rProp
= pProps
[ n
];
826 // Process Core properties.
828 if ( rProp
.Name
== "ContentType" )
830 xRow
->appendString ( rProp
, rData
.aContentType
);
832 else if ( rProp
.Name
== "Title" )
834 xRow
->appendString ( rProp
, rData
.aTitle
);
836 else if ( rProp
.Name
== "IsDocument" )
838 xRow
->appendBoolean( rProp
, rData
.bIsDocument
);
840 else if ( rProp
.Name
== "IsFolder" )
842 xRow
->appendBoolean( rProp
, rData
.bIsFolder
);
844 else if ( rProp
.Name
== "CreatableContentsInfo" )
848 rData
.getCreatableContentsInfo(
849 PackageUri( rContentId
) ) ) );
851 else if ( rProp
.Name
== "MediaType" )
853 xRow
->appendString ( rProp
, rData
.aMediaType
);
855 else if ( rProp
.Name
== "Size" )
857 // Property only available for streams.
858 if ( rData
.bIsDocument
)
859 xRow
->appendLong( rProp
, rData
.nSize
);
861 xRow
->appendVoid( rProp
);
863 else if ( rProp
.Name
== "Compressed" )
865 // Property only available for streams.
866 if ( rData
.bIsDocument
)
867 xRow
->appendBoolean( rProp
, rData
.bCompressed
);
869 xRow
->appendVoid( rProp
);
871 else if ( rProp
.Name
== "Encrypted" )
873 // Property only available for streams.
874 if ( rData
.bIsDocument
)
875 xRow
->appendBoolean( rProp
, rData
.bEncrypted
);
877 xRow
->appendVoid( rProp
);
879 else if ( rProp
.Name
== "HasEncryptedEntries" )
881 // Property only available for root folder.
882 PackageUri
aURI( rContentId
);
883 if ( aURI
.isRootFolder() )
884 xRow
->appendBoolean( rProp
, rData
.bHasEncryptedEntries
);
886 xRow
->appendVoid( rProp
);
890 // Not a Core Property! Maybe it's an Additional Core Property?!
892 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
895 = uno::Reference
< beans::XPropertySet
>(
896 rProvider
->getAdditionalPropertySet( rContentId
,
899 bTriedToGetAdditonalPropSet
= sal_True
;
902 if ( xAdditionalPropSet
.is() )
904 if ( !xRow
->appendPropertySetValue(
908 // Append empty entry.
909 xRow
->appendVoid( rProp
);
914 // Append empty entry.
915 xRow
->appendVoid( rProp
);
922 // Append all Core Properties.
925 OUString("ContentType"),
927 getCppuType( static_cast< const OUString
* >( 0 ) ),
928 beans::PropertyAttribute::BOUND
929 | beans::PropertyAttribute::READONLY
),
930 rData
.aContentType
);
935 getCppuType( static_cast< const OUString
* >( 0 ) ),
936 beans::PropertyAttribute::BOUND
),
940 OUString("IsDocument"),
942 getCppuBooleanType(),
943 beans::PropertyAttribute::BOUND
944 | beans::PropertyAttribute::READONLY
),
948 OUString("IsFolder"),
950 getCppuBooleanType(),
951 beans::PropertyAttribute::BOUND
952 | beans::PropertyAttribute::READONLY
),
956 OUString("CreatableContentsInfo"),
958 getCppuType( static_cast<
959 const uno::Sequence
< ucb::ContentInfo
> * >( 0 ) ),
960 beans::PropertyAttribute::BOUND
961 | beans::PropertyAttribute::READONLY
),
963 rData
.getCreatableContentsInfo( PackageUri( rContentId
) ) ) );
966 OUString("MediaType"),
968 getCppuType( static_cast< const OUString
* >( 0 ) ),
969 beans::PropertyAttribute::BOUND
),
972 // Properties only available for streams.
973 if ( rData
.bIsDocument
)
979 getCppuType( static_cast< const sal_Int64
* >( 0 ) ),
980 beans::PropertyAttribute::BOUND
981 | beans::PropertyAttribute::READONLY
),
986 OUString("Compressed"),
988 getCppuBooleanType(),
989 beans::PropertyAttribute::BOUND
),
994 OUString("Encrypted"),
996 getCppuBooleanType(),
997 beans::PropertyAttribute::BOUND
),
1001 // Properties only available for root folder.
1002 PackageUri
aURI( rContentId
);
1003 if ( aURI
.isRootFolder() )
1005 xRow
->appendBoolean(
1007 OUString("HasEncryptedEntries"),
1009 getCppuBooleanType(),
1010 beans::PropertyAttribute::BOUND
1011 | beans::PropertyAttribute::READONLY
),
1012 rData
.bHasEncryptedEntries
);
1015 // Append all Additional Core Properties.
1017 uno::Reference
< beans::XPropertySet
> xSet(
1018 rProvider
->getAdditionalPropertySet( rContentId
, sal_False
),
1020 xRow
->appendPropertySet( xSet
);
1023 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
1026 //=========================================================================
1027 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
1028 const uno::Sequence
< beans::Property
>& rProperties
)
1030 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1031 return getPropertyValues( m_xContext
,
1035 ::ucbhelper::ContentProviderImplHelper
>(
1036 m_xProvider
.get() ),
1037 m_xIdentifier
->getContentIdentifier() );
1040 //=========================================================================
1041 uno::Sequence
< uno::Any
> Content::setPropertyValues(
1042 const uno::Sequence
< beans::PropertyValue
>& rValues
,
1043 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1044 throw( uno::Exception
)
1046 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1048 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
1049 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
1050 sal_Int32 nChanged
= 0;
1052 beans::PropertyChangeEvent aEvent
;
1053 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
1054 aEvent
.Further
= sal_False
;
1055 // aEvent.PropertyName =
1056 aEvent
.PropertyHandle
= -1;
1057 // aEvent.OldValue =
1058 // aEvent.NewValue =
1060 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1061 sal_Int32 nCount
= rValues
.getLength();
1063 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1064 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
1065 sal_Bool bExchange
= sal_False
;
1066 sal_Bool bStore
= sal_False
;
1068 sal_Int32 nTitlePos
= -1;
1070 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1072 const beans::PropertyValue
& rValue
= pValues
[ n
];
1074 if ( rValue
.Name
== "ContentType" )
1076 // Read-only property!
1077 aRet
[ n
] <<= lang::IllegalAccessException(
1079 "Property is read-only!" ),
1080 static_cast< cppu::OWeakObject
* >( this ) );
1082 else if ( rValue
.Name
== "IsDocument" )
1084 // Read-only property!
1085 aRet
[ n
] <<= lang::IllegalAccessException(
1087 "Property is read-only!" ),
1088 static_cast< cppu::OWeakObject
* >( this ) );
1090 else if ( rValue
.Name
== "IsFolder" )
1092 // Read-only property!
1093 aRet
[ n
] <<= lang::IllegalAccessException(
1095 "Property is read-only!" ),
1096 static_cast< cppu::OWeakObject
* >( this ) );
1098 else if ( rValue
.Name
== "CreatableContentsInfo" )
1100 // Read-only property!
1101 aRet
[ n
] <<= lang::IllegalAccessException(
1103 "Property is read-only!" ),
1104 static_cast< cppu::OWeakObject
* >( this ) );
1106 else if ( rValue
.Name
== "Title" )
1108 if ( m_aUri
.isRootFolder() )
1110 // Read-only property!
1111 aRet
[ n
] <<= lang::IllegalAccessException(
1113 "Property is read-only!" ),
1114 static_cast< cppu::OWeakObject
* >( this ) );
1119 if ( rValue
.Value
>>= aNewValue
)
1122 if ( !aNewValue
.isEmpty() )
1124 if ( aNewValue
!= m_aProps
.aTitle
)
1126 // modified title -> modified URL -> exchange !
1127 if ( m_eState
== PERSISTENT
)
1128 bExchange
= sal_True
;
1130 // new value will be set later...
1131 aNewTitle
= aNewValue
;
1133 // remember position within sequence of values
1134 // (for error handling).
1141 lang::IllegalArgumentException(
1143 "Empty title not allowed!" ),
1144 static_cast< cppu::OWeakObject
* >( this ),
1151 beans::IllegalTypeException(
1153 "Property value has wrong type!" ),
1154 static_cast< cppu::OWeakObject
* >( this ) );
1158 else if ( rValue
.Name
== "MediaType" )
1161 if ( rValue
.Value
>>= aNewValue
)
1163 if ( aNewValue
!= m_aProps
.aMediaType
)
1165 aEvent
.PropertyName
= rValue
.Name
;
1166 aEvent
.OldValue
= uno::makeAny( m_aProps
.aMediaType
);
1167 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1169 m_aProps
.aMediaType
= aNewValue
;
1172 m_nModifiedProps
|= MEDIATYPE_MODIFIED
;
1177 aRet
[ n
] <<= beans::IllegalTypeException(
1179 "Property value has wrong type!" ),
1180 static_cast< cppu::OWeakObject
* >( this ) );
1183 else if ( rValue
.Name
== "Size" )
1185 // Read-only property!
1186 aRet
[ n
] <<= lang::IllegalAccessException(
1188 "Property is read-only!" ),
1189 static_cast< cppu::OWeakObject
* >( this ) );
1191 else if ( rValue
.Name
== "Compressed" )
1193 // Property only available for streams.
1194 if ( m_aProps
.bIsDocument
)
1197 if ( rValue
.Value
>>= bNewValue
)
1199 if ( bNewValue
!= m_aProps
.bCompressed
)
1201 aEvent
.PropertyName
= rValue
.Name
;
1202 aEvent
.OldValue
= uno::makeAny( m_aProps
.bCompressed
);
1203 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1205 m_aProps
.bCompressed
= bNewValue
;
1208 m_nModifiedProps
|= COMPRESSED_MODIFIED
;
1213 aRet
[ n
] <<= beans::IllegalTypeException(
1215 "Property value has wrong type!" ),
1216 static_cast< cppu::OWeakObject
* >( this ) );
1221 aRet
[ n
] <<= beans::UnknownPropertyException(
1223 "Compressed only supported by streams!" ),
1224 static_cast< cppu::OWeakObject
* >( this ) );
1227 else if ( rValue
.Name
== "Encrypted" )
1229 // Property only available for streams.
1230 if ( m_aProps
.bIsDocument
)
1233 if ( rValue
.Value
>>= bNewValue
)
1235 if ( bNewValue
!= m_aProps
.bEncrypted
)
1237 aEvent
.PropertyName
= rValue
.Name
;
1238 aEvent
.OldValue
= uno::makeAny( m_aProps
.bEncrypted
);
1239 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1241 m_aProps
.bEncrypted
= bNewValue
;
1244 m_nModifiedProps
|= ENCRYPTED_MODIFIED
;
1249 aRet
[ n
] <<= beans::IllegalTypeException(
1251 "Property value has wrong type!" ),
1252 static_cast< cppu::OWeakObject
* >( this ) );
1257 aRet
[ n
] <<= beans::UnknownPropertyException(
1259 "Encrypted only supported by streams!" ),
1260 static_cast< cppu::OWeakObject
* >( this ) );
1263 else if ( rValue
.Name
== "HasEncryptedEntries" )
1265 // Read-only property!
1266 aRet
[ n
] <<= lang::IllegalAccessException(
1268 "Property is read-only!" ),
1269 static_cast< cppu::OWeakObject
* >( this ) );
1271 else if ( rValue
.Name
== "EncryptionKey" )
1273 // @@@ This is a temporary solution. In the future submitting
1274 // the key should be done using an interaction handler!
1276 // Write-Only property. Only supported by root folder and streams
1277 // (all non-root folders of a package have the same encryption key).
1278 if ( m_aUri
.isRootFolder() || m_aProps
.bIsDocument
)
1280 uno::Sequence
< sal_Int8
> aNewValue
;
1281 if ( rValue
.Value
>>= aNewValue
)
1283 if ( aNewValue
!= m_aProps
.aEncryptionKey
)
1285 aEvent
.PropertyName
= rValue
.Name
;
1286 aEvent
.OldValue
= uno::makeAny(
1287 m_aProps
.aEncryptionKey
);
1288 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1290 m_aProps
.aEncryptionKey
= aNewValue
;
1293 m_nModifiedProps
|= ENCRYPTIONKEY_MODIFIED
;
1298 aRet
[ n
] <<= beans::IllegalTypeException(
1300 "Property value has wrong type!" ),
1301 static_cast< cppu::OWeakObject
* >( this ) );
1306 aRet
[ n
] <<= beans::UnknownPropertyException(
1308 "EncryptionKey not supported by non-root folder!" ),
1309 static_cast< cppu::OWeakObject
* >( this ) );
1314 // Not a Core Property! Maybe it's an Additional Core Property?!
1316 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
1318 xAdditionalPropSet
= getAdditionalPropertySet( sal_False
);
1319 bTriedToGetAdditonalPropSet
= sal_True
;
1322 if ( xAdditionalPropSet
.is() )
1327 = xAdditionalPropSet
->getPropertyValue( rValue
.Name
);
1328 if ( aOldValue
!= rValue
.Value
)
1330 xAdditionalPropSet
->setPropertyValue(
1331 rValue
.Name
, rValue
.Value
);
1333 aEvent
.PropertyName
= rValue
.Name
;
1334 aEvent
.OldValue
= aOldValue
;
1335 aEvent
.NewValue
= rValue
.Value
;
1337 aChanges
.getArray()[ nChanged
] = aEvent
;
1341 catch ( beans::UnknownPropertyException
const & e
)
1345 catch ( lang::WrappedTargetException
const & e
)
1349 catch ( beans::PropertyVetoException
const & e
)
1353 catch ( lang::IllegalArgumentException
const & e
)
1360 aRet
[ n
] <<= uno::Exception(
1362 "No property set for storing the value!" ),
1363 static_cast< cppu::OWeakObject
* >( this ) );
1370 uno::Reference
< ucb::XContentIdentifier
> xOldId
= m_xIdentifier
;
1372 // Assemble new content identifier...
1373 OUString aNewURL
= m_aUri
.getParentUri();
1374 aNewURL
+= OUString("/");
1375 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( aNewTitle
);
1376 uno::Reference
< ucb::XContentIdentifier
> xNewId
1377 = new ::ucbhelper::ContentIdentifier( aNewURL
);
1380 if ( exchangeIdentity( xNewId
) )
1382 // Adapt persistent data.
1383 renameData( xOldId
, xNewId
);
1385 // Adapt Additional Core Properties.
1386 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1387 xNewId
->getContentIdentifier(),
1392 // Do not set new title!
1393 aNewTitle
= OUString();
1396 aRet
[ nTitlePos
] <<= uno::Exception(
1397 OUString("Exchange failed!"),
1398 static_cast< cppu::OWeakObject
* >( this ) );
1402 if ( !aNewTitle
.isEmpty() )
1404 aEvent
.PropertyName
= OUString("Title");
1405 aEvent
.OldValue
= uno::makeAny( m_aProps
.aTitle
);
1406 aEvent
.NewValue
= uno::makeAny( aNewTitle
);
1408 m_aProps
.aTitle
= aNewTitle
;
1410 aChanges
.getArray()[ nChanged
] = aEvent
;
1416 // Save changes, if content was already made persistent.
1417 if ( ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
) ||
1418 ( bStore
&& ( m_eState
== PERSISTENT
) ) )
1420 if ( !storeData( uno::Reference
< io::XInputStream
>() ) )
1424 beans::PropertyValue(
1428 uno::makeAny(m_xIdentifier
->
1429 getContentIdentifier()),
1430 beans::PropertyState_DIRECT_VALUE
));
1431 ucbhelper::cancelCommandExecution(
1432 ucb::IOErrorCode_CANT_WRITE
,
1433 uno::Sequence
< uno::Any
>(&aProps
, 1),
1436 "Cannot store persistent data!" ),
1443 aChanges
.realloc( nChanged
);
1444 notifyPropertiesChange( aChanges
);
1450 //=========================================================================
1451 uno::Any
Content::open(
1452 const ucb::OpenCommandArgument2
& rArg
,
1453 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1454 throw( uno::Exception
)
1456 if ( rArg
.Mode
== ucb::OpenMode::ALL
||
1457 rArg
.Mode
== ucb::OpenMode::FOLDERS
||
1458 rArg
.Mode
== ucb::OpenMode::DOCUMENTS
)
1460 //////////////////////////////////////////////////////////////////
1461 // open command for a folder content
1462 //////////////////////////////////////////////////////////////////
1464 uno::Reference
< ucb::XDynamicResultSet
> xSet
1465 = new DynamicResultSet( m_xContext
, this, rArg
, xEnv
);
1466 return uno::makeAny( xSet
);
1470 //////////////////////////////////////////////////////////////////
1471 // open command for a document content
1472 //////////////////////////////////////////////////////////////////
1474 if ( ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
1475 ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
) )
1477 // Currently(?) unsupported.
1478 ucbhelper::cancelCommandExecution(
1479 uno::makeAny( ucb::UnsupportedOpenModeException(
1481 static_cast< cppu::OWeakObject
* >( this ),
1482 sal_Int16( rArg
.Mode
) ) ),
1487 uno::Reference
< io::XOutputStream
> xOut( rArg
.Sink
, uno::UNO_QUERY
);
1490 // PUSH: write data into xOut
1492 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1495 // No interaction if we are not persistent!
1498 beans::PropertyValue(
1502 uno::makeAny(m_xIdentifier
->
1503 getContentIdentifier()),
1504 beans::PropertyState_DIRECT_VALUE
));
1505 ucbhelper::cancelCommandExecution(
1506 ucb::IOErrorCode_CANT_READ
,
1507 uno::Sequence
< uno::Any
>(&aProps
, 1),
1508 m_eState
== PERSISTENT
1510 : uno::Reference
< ucb::XCommandEnvironment
>(),
1511 OUString("Got no data stream!"),
1518 uno::Sequence
< sal_Int8
> aBuffer
;
1519 sal_Int32 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1523 aBuffer
.realloc( nRead
);
1524 xOut
->writeBytes( aBuffer
);
1525 aBuffer
.realloc( 0 );
1526 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1529 xOut
->closeOutput();
1531 catch ( io::NotConnectedException
const & )
1533 // closeOutput, readSomeBytes, writeBytes
1535 catch ( io::BufferSizeExceededException
const & )
1537 // closeOutput, readSomeBytes, writeBytes
1539 catch ( io::IOException
const & )
1541 // closeOutput, readSomeBytes, writeBytes
1546 uno::Reference
< io::XActiveDataSink
> xDataSink(
1547 rArg
.Sink
, uno::UNO_QUERY
);
1548 if ( xDataSink
.is() )
1550 // PULL: wait for client read
1552 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1555 // No interaction if we are not persistent!
1558 beans::PropertyValue(
1561 uno::makeAny(m_xIdentifier
->
1562 getContentIdentifier()),
1563 beans::PropertyState_DIRECT_VALUE
));
1564 ucbhelper::cancelCommandExecution(
1565 ucb::IOErrorCode_CANT_READ
,
1566 uno::Sequence
< uno::Any
>(&aProps
, 1),
1567 m_eState
== PERSISTENT
1570 ucb::XCommandEnvironment
>(),
1571 OUString( "Got no data stream!" ),
1577 xDataSink
->setInputStream( xIn
);
1581 // Note: aOpenCommand.Sink may contain an XStream
1582 // implementation. Support for this type of
1583 // sink is optional...
1584 ucbhelper::cancelCommandExecution(
1586 ucb::UnsupportedDataSinkException(
1588 static_cast< cppu::OWeakObject
* >( this ),
1599 //=========================================================================
1600 void Content::insert(
1601 const uno::Reference
< io::XInputStream
>& xStream
,
1602 sal_Int32 nNameClashResolve
,
1603 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1604 throw( uno::Exception
)
1606 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1608 // Check, if all required properties were set.
1613 if ( m_aProps
.aTitle
.isEmpty() )
1614 m_aProps
.aTitle
= m_aUri
.getName();
1618 // Required: rArg.Data
1620 if ( !xStream
.is() )
1622 ucbhelper::cancelCommandExecution(
1623 uno::makeAny( ucb::MissingInputStreamException(
1625 static_cast< cppu::OWeakObject
* >( this ) ) ),
1632 if ( m_aProps
.aTitle
.isEmpty() )
1633 m_aProps
.aTitle
= m_aUri
.getName();
1636 OUString aNewURL
= m_aUri
.getParentUri();
1637 if (1 + aNewURL
.lastIndexOf('/') != aNewURL
.getLength())
1638 aNewURL
+= OUString("/");
1639 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( m_aProps
.aTitle
);
1640 PackageUri
aNewUri( aNewURL
);
1642 // Handle possible name clash...
1643 switch ( nNameClashResolve
)
1646 case ucb::NameClash::ERROR
:
1647 if ( hasData( aNewUri
) )
1649 ucbhelper::cancelCommandExecution(
1650 uno::makeAny( ucb::NameClashException(
1652 static_cast< cppu::OWeakObject
* >( this ),
1653 task::InteractionClassification_ERROR
,
1654 m_aProps
.aTitle
) ),
1660 // replace (possibly) existing object.
1661 case ucb::NameClash::OVERWRITE
:
1664 // "invent" a new valid title.
1665 case ucb::NameClash::RENAME
:
1666 if ( hasData( aNewUri
) )
1672 OUString aNew
= aNewUri
.getUri();
1673 aNew
+= OUString("_");
1674 aNew
+= OUString::valueOf( ++nTry
);
1675 aNewUri
.setUri( aNew
);
1677 while ( hasData( aNewUri
) && ( nTry
< 1000 ) );
1681 ucbhelper::cancelCommandExecution(
1683 ucb::UnsupportedNameClashException(
1684 OUString( "Unable to resolve name clash!" ),
1685 static_cast< cppu::OWeakObject
* >( this ),
1686 nNameClashResolve
) ),
1692 m_aProps
.aTitle
+= OUString("_");
1693 m_aProps
.aTitle
+= OUString::valueOf( nTry
);
1698 case ucb::NameClash::KEEP
: // deprecated
1699 case ucb::NameClash::ASK
:
1701 if ( hasData( aNewUri
) )
1703 ucbhelper::cancelCommandExecution(
1705 ucb::UnsupportedNameClashException(
1707 static_cast< cppu::OWeakObject
* >( this ),
1708 nNameClashResolve
) ),
1715 // Identifier changed?
1716 sal_Bool bNewId
= ( m_aUri
.getUri() != aNewUri
.getUri() );
1720 m_xIdentifier
= new ::ucbhelper::ContentIdentifier( aNewURL
);
1724 if ( !storeData( xStream
) )
1727 = uno::makeAny(beans::PropertyValue(
1730 uno::makeAny(m_xIdentifier
->
1731 getContentIdentifier()),
1732 beans::PropertyState_DIRECT_VALUE
));
1733 ucbhelper::cancelCommandExecution(
1734 ucb::IOErrorCode_CANT_WRITE
,
1735 uno::Sequence
< uno::Any
>(&aProps
, 1),
1737 OUString("Cannot store persistent data!"),
1742 m_eState
= PERSISTENT
;
1746 // Take over correct default values from underlying packager...
1747 uno::Reference
< container::XHierarchicalNameAccess
> xXHierarchicalNameAccess
;
1748 loadData( m_pProvider
,
1751 xXHierarchicalNameAccess
);
1758 //=========================================================================
1759 void Content::destroy(
1760 sal_Bool bDeletePhysical
,
1761 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1762 throw( uno::Exception
)
1764 // @@@ take care about bDeletePhysical -> trashcan support
1766 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1768 uno::Reference
< ucb::XContent
> xThis
= this;
1771 if ( m_eState
!= PERSISTENT
)
1773 ucbhelper::cancelCommandExecution(
1774 uno::makeAny( ucb::UnsupportedCommandException(
1775 OUString( "Not persistent!" ),
1776 static_cast< cppu::OWeakObject
* >( this ) ) ),
1788 // Process instanciated children...
1790 ContentRefList aChildren
;
1791 queryChildren( aChildren
);
1793 ContentRefList::const_iterator it
= aChildren
.begin();
1794 ContentRefList::const_iterator end
= aChildren
.end();
1798 (*it
)->destroy( bDeletePhysical
, xEnv
);
1804 //=========================================================================
1805 void Content::transfer(
1806 const ucb::TransferInfo
& rInfo
,
1807 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1808 throw( uno::Exception
)
1810 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1813 if ( m_eState
!= PERSISTENT
)
1815 ucbhelper::cancelCommandExecution(
1816 uno::makeAny( ucb::UnsupportedCommandException(
1817 OUString( "Not persistent!" ),
1818 static_cast< cppu::OWeakObject
* >( this ) ) ),
1823 // Is source a package content?
1824 if ( ( rInfo
.SourceURL
.isEmpty() ) ||
1825 ( rInfo
.SourceURL
.compareTo(
1826 m_aUri
.getUri(), PACKAGE_URL_SCHEME_LENGTH
+ 3 ) != 0 ) )
1828 ucbhelper::cancelCommandExecution(
1829 uno::makeAny( ucb::InteractiveBadTransferURLException(
1831 static_cast< cppu::OWeakObject
* >( this ) ) ),
1836 // Is source not a parent of me / not me?
1837 OUString aId
= m_aUri
.getParentUri();
1838 aId
+= OUString("/");
1840 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1843 rInfo
.SourceURL
, rInfo
.SourceURL
.getLength() ) == 0 )
1846 = uno::makeAny(beans::PropertyValue(
1849 uno::makeAny(rInfo
.SourceURL
),
1850 beans::PropertyState_DIRECT_VALUE
));
1851 ucbhelper::cancelCommandExecution(
1852 ucb::IOErrorCode_RECURSIVE
,
1853 uno::Sequence
< uno::Any
>(&aProps
, 1),
1855 OUString( "Target is equal to or is a child of source!" ),
1861 //////////////////////////////////////////////////////////////////////
1862 // 0) Obtain content object for source.
1863 //////////////////////////////////////////////////////////////////////
1865 uno::Reference
< ucb::XContentIdentifier
> xId
1866 = new ::ucbhelper::ContentIdentifier( rInfo
.SourceURL
);
1868 // Note: The static cast is okay here, because its sure that
1869 // m_xProvider is always the PackageContentProvider.
1870 rtl::Reference
< Content
> xSource
;
1874 xSource
= static_cast< Content
* >(
1875 m_xProvider
->queryContent( xId
).get() );
1877 catch ( ucb::IllegalIdentifierException
const & )
1882 if ( !xSource
.is() )
1885 = uno::makeAny(beans::PropertyValue(
1888 uno::makeAny(xId
->getContentIdentifier()),
1889 beans::PropertyState_DIRECT_VALUE
));
1890 ucbhelper::cancelCommandExecution(
1891 ucb::IOErrorCode_CANT_READ
,
1892 uno::Sequence
< uno::Any
>(&aProps
, 1),
1894 OUString( "Cannot instanciate source object!" ),
1899 //////////////////////////////////////////////////////////////////////
1900 // 1) Create new child content.
1901 //////////////////////////////////////////////////////////////////////
1903 OUString aType
= xSource
->isFolder()
1904 ? getContentType( m_aUri
.getScheme(), sal_True
)
1905 : getContentType( m_aUri
.getScheme(), sal_False
);
1906 ucb::ContentInfo aContentInfo
;
1907 aContentInfo
.Type
= aType
;
1908 aContentInfo
.Attributes
= 0;
1910 // Note: The static cast is okay here, because its sure that
1911 // createNewContent always creates a Content.
1912 rtl::Reference
< Content
> xTarget
1913 = static_cast< Content
* >( createNewContent( aContentInfo
).get() );
1914 if ( !xTarget
.is() )
1917 = uno::makeAny(beans::PropertyValue(
1918 OUString( "Folder"),
1921 beans::PropertyState_DIRECT_VALUE
));
1922 ucbhelper::cancelCommandExecution(
1923 ucb::IOErrorCode_CANT_CREATE
,
1924 uno::Sequence
< uno::Any
>(&aProps
, 1),
1926 OUString( "XContentCreator::createNewContent failed!" ),
1931 //////////////////////////////////////////////////////////////////////
1932 // 2) Copy data from source content to child content.
1933 //////////////////////////////////////////////////////////////////////
1935 uno::Sequence
< beans::Property
> aSourceProps
1936 = xSource
->getPropertySetInfo( xEnv
)->getProperties();
1937 sal_Int32 nCount
= aSourceProps
.getLength();
1941 sal_Bool bHadTitle
= rInfo
.NewTitle
.isEmpty();
1943 // Get all source values.
1944 uno::Reference
< sdbc::XRow
> xRow
1945 = xSource
->getPropertyValues( aSourceProps
);
1947 uno::Sequence
< beans::PropertyValue
> aValues( nCount
);
1948 beans::PropertyValue
* pValues
= aValues
.getArray();
1950 const beans::Property
* pProps
= aSourceProps
.getConstArray();
1951 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1953 const beans::Property
& rProp
= pProps
[ n
];
1954 beans::PropertyValue
& rValue
= pValues
[ n
];
1956 rValue
.Name
= rProp
.Name
;
1957 rValue
.Handle
= rProp
.Handle
;
1959 if ( !bHadTitle
&& rProp
.Name
== "Title" )
1961 // Set new title instead of original.
1962 bHadTitle
= sal_True
;
1963 rValue
.Value
<<= rInfo
.NewTitle
;
1967 = xRow
->getObject( n
+ 1,
1969 container::XNameAccess
>() );
1971 rValue
.State
= beans::PropertyState_DIRECT_VALUE
;
1973 if ( rProp
.Attributes
& beans::PropertyAttribute::REMOVABLE
)
1975 // Add Additional Core Property.
1978 xTarget
->addProperty( rProp
.Name
,
1982 catch ( beans::PropertyExistException
const & )
1985 catch ( beans::IllegalTypeException
const & )
1988 catch ( lang::IllegalArgumentException
const & )
1994 // Set target values.
1995 xTarget
->setPropertyValues( aValues
, xEnv
);
1998 //////////////////////////////////////////////////////////////////////
1999 // 3) Commit (insert) child.
2000 //////////////////////////////////////////////////////////////////////
2002 xTarget
->insert( xSource
->getInputStream(), rInfo
.NameClash
, xEnv
);
2004 //////////////////////////////////////////////////////////////////////
2005 // 4) Transfer (copy) children of source.
2006 //////////////////////////////////////////////////////////////////////
2008 if ( xSource
->isFolder() )
2010 uno::Reference
< container::XEnumeration
> xIter
2011 = xSource
->getIterator();
2014 while ( xIter
->hasMoreElements() )
2018 uno::Reference
< container::XNamed
> xNamed
;
2019 xIter
->nextElement() >>= xNamed
;
2023 OSL_FAIL( "Content::transfer - Got no XNamed!" );
2027 OUString aName
= xNamed
->getName();
2029 if ( aName
.isEmpty() )
2031 OSL_FAIL( "Content::transfer - Empty name!" );
2035 OUString aChildId
= xId
->getContentIdentifier();
2036 if ( ( aChildId
.lastIndexOf( '/' ) + 1 )
2037 != aChildId
.getLength() )
2038 aChildId
+= OUString("/");
2040 aChildId
+= ::ucb_impl::urihelper::encodeSegment( aName
);
2042 ucb::TransferInfo aInfo
;
2043 aInfo
.MoveData
= sal_False
;
2044 aInfo
.NewTitle
= OUString();
2045 aInfo
.SourceURL
= aChildId
;
2046 aInfo
.NameClash
= rInfo
.NameClash
;
2048 // Transfer child to target.
2049 xTarget
->transfer( aInfo
, xEnv
);
2051 catch ( container::NoSuchElementException
const & )
2054 catch ( lang::WrappedTargetException
const & )
2061 //////////////////////////////////////////////////////////////////////
2062 // 5) Destroy source ( when moving only ) .
2063 //////////////////////////////////////////////////////////////////////
2065 if ( rInfo
.MoveData
)
2067 xSource
->destroy( sal_True
, xEnv
);
2069 // Remove all persistent data of source and its children.
2070 if ( !xSource
->removeData() )
2074 beans::PropertyValue(
2078 xSource
->m_xIdentifier
->
2079 getContentIdentifier()),
2080 beans::PropertyState_DIRECT_VALUE
));
2081 ucbhelper::cancelCommandExecution(
2082 ucb::IOErrorCode_CANT_WRITE
,
2083 uno::Sequence
< uno::Any
>(&aProps
, 1),
2085 OUString( "Cannot remove persistent data of source object!" ),
2090 // Remove own and all children's Additional Core Properties.
2091 xSource
->removeAdditionalPropertySet( sal_True
);
2095 //=========================================================================
2096 sal_Bool
Content::exchangeIdentity(
2097 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2102 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
2104 uno::Reference
< ucb::XContent
> xThis
= this;
2106 // Already persistent?
2107 if ( m_eState
!= PERSISTENT
)
2109 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2113 // Exchange own identitity.
2115 // Fail, if a content with given id already exists.
2116 PackageUri
aNewUri( xNewId
->getContentIdentifier() );
2117 if ( !hasData( aNewUri
) )
2119 OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
2122 if ( exchange( xNewId
) )
2127 // Process instanciated children...
2129 ContentRefList aChildren
;
2130 queryChildren( aChildren
);
2132 ContentRefList::const_iterator it
= aChildren
.begin();
2133 ContentRefList::const_iterator end
= aChildren
.end();
2137 ContentRef xChild
= (*it
);
2139 // Create new content identifier for the child...
2140 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
2141 = xChild
->getIdentifier();
2142 OUString aOldChildURL
2143 = xOldChildId
->getContentIdentifier();
2144 OUString aNewChildURL
2145 = aOldChildURL
.replaceAt(
2147 aOldURL
.getLength(),
2148 xNewId
->getContentIdentifier() );
2149 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
2150 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
2152 if ( !xChild
->exchangeIdentity( xNewChildId
) )
2162 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2166 //=========================================================================
2167 void Content::queryChildren( ContentRefList
& rChildren
)
2169 // Obtain a list with a snapshot of all currently instanciated contents
2170 // from provider and extract the contents which are direct children
2173 ::ucbhelper::ContentRefList aAllContents
;
2174 m_xProvider
->queryExistingContents( aAllContents
);
2176 OUString aURL
= m_xIdentifier
->getContentIdentifier();
2178 OSL_ENSURE( aURL
.lastIndexOf( '/' ) != ( aURL
.getLength() - 1 ),
2179 "Content::queryChildren - Invalid URL!" );
2181 aURL
+= OUString("/");
2183 sal_Int32 nLen
= aURL
.getLength();
2185 ::ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
2186 ::ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
2190 ::ucbhelper::ContentImplHelperRef xChild
= (*it
);
2192 = xChild
->getIdentifier()->getContentIdentifier();
2194 // Is aURL a prefix of aChildURL?
2195 if ( ( aChildURL
.getLength() > nLen
) &&
2196 ( aChildURL
.compareTo( aURL
, nLen
) == 0 ) )
2198 if ( aChildURL
.indexOf( '/', nLen
) == -1 )
2200 // No further slashes. It's a child!
2201 rChildren
.push_back(
2203 static_cast< Content
* >( xChild
.get() ) ) );
2210 //=========================================================================
2211 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage(
2212 const PackageUri
& rURI
)
2214 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2216 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2217 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2219 if ( !m_xPackage
.is() )
2220 m_xPackage
= m_pProvider
->createPackage( m_aUri
.getPackage(), m_aUri
.getParam() );
2225 return m_pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2228 //=========================================================================
2229 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage()
2231 return getPackage( m_aUri
);
2234 //=========================================================================
2236 sal_Bool
Content::hasData(
2237 ContentProvider
* pProvider
,
2238 const PackageUri
& rURI
,
2239 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2241 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2242 if ( !rxPackage
.is() )
2245 return rxPackage
->hasByHierarchicalName( rURI
.getPath() );
2248 //=========================================================================
2249 sal_Bool
Content::hasData( const PackageUri
& rURI
)
2251 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2253 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2254 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2256 xPackage
= getPackage();
2257 if ( !xPackage
.is() )
2260 return xPackage
->hasByHierarchicalName( rURI
.getPath() );
2263 return hasData( m_pProvider
, rURI
, xPackage
);
2266 //=========================================================================
2268 sal_Bool
Content::loadData(
2269 ContentProvider
* pProvider
,
2270 const PackageUri
& rURI
,
2271 ContentProperties
& rProps
,
2272 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2274 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2275 if ( !rxPackage
.is() )
2278 if ( rURI
.isRootFolder() )
2280 // Properties available only from package
2281 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2282 rxPackage
, uno::UNO_QUERY
);
2284 OSL_ENSURE( xPackagePropSet
.is(),
2285 "Content::loadData - "
2286 "Got no XPropertySet interface from package!" );
2288 if ( xPackagePropSet
.is() )
2290 // HasEncryptedEntries ( only avalibale at root folder )
2293 uno::Any aHasEncryptedEntries
2294 = xPackagePropSet
->getPropertyValue(
2295 OUString( "HasEncryptedEntries" ) );
2296 if ( !( aHasEncryptedEntries
>>= rProps
.bHasEncryptedEntries
) )
2298 OSL_FAIL( "Content::loadData - "
2299 "Got no HasEncryptedEntries value!" );
2303 catch ( beans::UnknownPropertyException
const & )
2305 OSL_FAIL( "Content::loadData - "
2306 "Got no HasEncryptedEntries value!" );
2309 catch ( lang::WrappedTargetException
const & )
2311 OSL_FAIL( "Content::loadData - "
2312 "Got no HasEncryptedEntries value!" );
2318 if ( !rxPackage
->hasByHierarchicalName( rURI
.getPath() ) )
2323 uno::Any aEntry
= rxPackage
->getByHierarchicalName( rURI
.getPath() );
2324 if ( aEntry
.hasValue() )
2326 uno::Reference
< beans::XPropertySet
> xPropSet
;
2327 aEntry
>>= xPropSet
;
2329 if ( !xPropSet
.is() )
2331 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2336 rProps
.aTitle
= rURI
.getName();
2342 = xPropSet
->getPropertyValue(
2343 OUString("MediaType") );
2344 if ( !( aMediaType
>>= rProps
.aMediaType
) )
2346 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2350 catch ( beans::UnknownPropertyException
const & )
2352 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2355 catch ( lang::WrappedTargetException
const & )
2357 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2361 uno::Reference
< container::XEnumerationAccess
> xEnumAccess
;
2362 aEntry
>>= xEnumAccess
;
2364 // ContentType / IsFolder / IsDocument
2365 if ( xEnumAccess
.is() )
2368 rProps
.aContentType
= getContentType( rURI
.getScheme(), sal_True
);
2369 rProps
.bIsDocument
= sal_False
;
2370 rProps
.bIsFolder
= sal_True
;
2375 rProps
.aContentType
= getContentType( rURI
.getScheme(), sal_False
);
2376 rProps
.bIsDocument
= sal_True
;
2377 rProps
.bIsFolder
= sal_False
;
2380 if ( rProps
.bIsDocument
)
2382 // Size ( only available for streams )
2386 = xPropSet
->getPropertyValue(
2388 if ( !( aSize
>>= rProps
.nSize
) )
2390 OSL_FAIL( "Content::loadData - Got no Size value!" );
2394 catch ( beans::UnknownPropertyException
const & )
2396 OSL_FAIL( "Content::loadData - Got no Size value!" );
2399 catch ( lang::WrappedTargetException
const & )
2401 OSL_FAIL( "Content::loadData - Got no Size value!" );
2405 // Compressed ( only available for streams )
2408 uno::Any aCompressed
2409 = xPropSet
->getPropertyValue(
2410 OUString("Compressed") );
2411 if ( !( aCompressed
>>= rProps
.bCompressed
) )
2413 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2417 catch ( beans::UnknownPropertyException
const & )
2419 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2422 catch ( lang::WrappedTargetException
const & )
2424 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2428 // Encrypted ( only available for streams )
2432 = xPropSet
->getPropertyValue(
2433 OUString("Encrypted") );
2434 if ( !( aEncrypted
>>= rProps
.bEncrypted
) )
2436 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2440 catch ( beans::UnknownPropertyException
const & )
2442 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2445 catch ( lang::WrappedTargetException
const & )
2447 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2454 catch ( container::NoSuchElementException
const & )
2456 // getByHierarchicalName
2462 //=========================================================================
2463 sal_Bool
Content::renameData(
2464 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
2465 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2467 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2469 PackageUri
aURI( xOldId
->getContentIdentifier() );
2470 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage(
2475 if ( !xNA
->hasByHierarchicalName( aURI
.getPath() ) )
2480 uno::Any aEntry
= xNA
->getByHierarchicalName( aURI
.getPath() );
2481 uno::Reference
< container::XNamed
> xNamed
;
2486 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2490 PackageUri
aNewURI( xNewId
->getContentIdentifier() );
2492 // No success indicator!? No return value / exceptions specified.
2493 xNamed
->setName( aNewURI
.getName() );
2497 catch ( container::NoSuchElementException
const & )
2499 // getByHierarchicalName
2505 //=========================================================================
2506 sal_Bool
Content::storeData( const uno::Reference
< io::XInputStream
>& xStream
)
2508 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2510 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2514 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2515 xNA
, uno::UNO_QUERY
);
2516 OSL_ENSURE( xPackagePropSet
.is(),
2517 "Content::storeData - "
2518 "Got no XPropertySet interface from package!" );
2520 if ( !xPackagePropSet
.is() )
2523 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2525 if ( m_aUri
.isRootFolder() )
2527 // Property available only from package and from streams (see below)
2530 xPackagePropSet
->setPropertyValue(
2531 OUString("EncryptionKey"),
2532 uno::makeAny( m_aProps
.aEncryptionKey
) );
2533 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2535 catch ( beans::UnknownPropertyException
const & )
2539 catch ( beans::PropertyVetoException
const & )
2543 catch ( lang::IllegalArgumentException
const & )
2547 catch ( lang::WrappedTargetException
const & )
2554 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2561 // Create new resource...
2562 uno::Reference
< lang::XSingleServiceFactory
> xFac(
2563 xNA
, uno::UNO_QUERY
);
2566 OSL_FAIL( "Content::storeData - "
2567 "Got no XSingleServiceFactory interface!" );
2571 uno::Sequence
< uno::Any
> aArgs( 1 );
2572 aArgs
[ 0 ] <<= isFolder();
2574 uno::Reference
< uno::XInterface
> xNew
2575 = xFac
->createInstanceWithArguments( aArgs
);
2579 OSL_FAIL( "Content::storeData - createInstance failed!" );
2583 PackageUri
aParentUri( getParentURL() );
2585 = xNA
->getByHierarchicalName( aParentUri
.getPath() );
2586 uno::Reference
< container::XNameContainer
> xParentContainer
;
2587 aEntry
>>= xParentContainer
;
2589 if ( !xParentContainer
.is() )
2591 OSL_FAIL( "Content::storeData - "
2592 "Got no XNameContainer interface!" );
2596 xParentContainer
->insertByName( m_aProps
.aTitle
,
2597 uno::makeAny( xNew
) );
2599 catch ( lang::IllegalArgumentException
const & )
2602 OSL_FAIL( "Content::storeData - insertByName failed!" );
2605 catch ( uno::RuntimeException
const & )
2609 catch ( container::ElementExistException
const & )
2612 OSL_FAIL( "Content::storeData - insertByName failed!" );
2615 catch ( lang::WrappedTargetException
const & )
2618 OSL_FAIL( "Content::storeData - insertByName failed!" );
2621 catch ( container::NoSuchElementException
const & )
2623 // getByHierarchicalName
2624 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2627 catch ( uno::Exception
const & )
2629 // createInstanceWithArguments
2630 OSL_FAIL( "Content::storeData - Error!" );
2635 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2640 uno::Reference
< beans::XPropertySet
> xPropSet
;
2641 xNA
->getByHierarchicalName( m_aUri
.getPath() ) >>= xPropSet
;
2643 if ( !xPropSet
.is() )
2645 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2649 //////////////////////////////////////////////////////////////////
2650 // Store property values...
2651 //////////////////////////////////////////////////////////////////
2653 if ( m_nModifiedProps
& MEDIATYPE_MODIFIED
)
2655 xPropSet
->setPropertyValue(
2656 OUString("MediaType"),
2657 uno::makeAny( m_aProps
.aMediaType
) );
2658 m_nModifiedProps
&= ~MEDIATYPE_MODIFIED
;
2661 if ( m_nModifiedProps
& COMPRESSED_MODIFIED
)
2664 xPropSet
->setPropertyValue(
2665 OUString("Compressed"),
2666 uno::makeAny( m_aProps
.bCompressed
) );
2668 m_nModifiedProps
&= ~COMPRESSED_MODIFIED
;
2671 if ( m_nModifiedProps
& ENCRYPTED_MODIFIED
)
2674 xPropSet
->setPropertyValue(
2675 OUString("Encrypted"),
2676 uno::makeAny( m_aProps
.bEncrypted
) );
2678 m_nModifiedProps
&= ~ENCRYPTED_MODIFIED
;
2681 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2684 xPropSet
->setPropertyValue(
2685 OUString("EncryptionKey"),
2686 uno::makeAny( m_aProps
.aEncryptionKey
) );
2688 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2691 //////////////////////////////////////////////////////////////////
2692 // Store data stream...
2693 //////////////////////////////////////////////////////////////////
2695 if ( xStream
.is() && !isFolder() )
2697 uno::Reference
< io::XActiveDataSink
> xSink(
2698 xPropSet
, uno::UNO_QUERY
);
2702 OSL_FAIL( "Content::storeData - "
2703 "Got no XActiveDataSink interface!" );
2707 xSink
->setInputStream( xStream
);
2712 catch ( container::NoSuchElementException
const & )
2714 // getByHierarchicalName
2716 catch ( beans::UnknownPropertyException
const & )
2720 catch ( beans::PropertyVetoException
const & )
2724 catch ( lang::IllegalArgumentException
const & )
2728 catch ( lang::WrappedTargetException
const & )
2733 OSL_FAIL( "Content::storeData - Error!" );
2737 //=========================================================================
2738 sal_Bool
Content::removeData()
2740 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2742 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2746 PackageUri
aParentUri( getParentURL() );
2747 if ( !xNA
->hasByHierarchicalName( aParentUri
.getPath() ) )
2752 uno::Any aEntry
= xNA
->getByHierarchicalName( aParentUri
.getPath() );
2753 uno::Reference
< container::XNameContainer
> xContainer
;
2754 aEntry
>>= xContainer
;
2756 if ( !xContainer
.is() )
2758 OSL_FAIL( "Content::removeData - "
2759 "Got no XNameContainer interface!" );
2763 xContainer
->removeByName( m_aUri
.getName() );
2766 catch ( container::NoSuchElementException
const & )
2768 // getByHierarchicalName, removeByName
2770 catch ( lang::WrappedTargetException
const & )
2775 OSL_FAIL( "Content::removeData - Error!" );
2779 //=========================================================================
2780 sal_Bool
Content::flushData()
2782 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2784 // Note: XChangesBatch is only implemented by the package itself, not
2785 // by the single entries. Maybe this has to change...
2787 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2791 uno::Reference
< util::XChangesBatch
> xBatch( xNA
, uno::UNO_QUERY
);
2794 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2800 xBatch
->commitChanges();
2803 catch ( lang::WrappedTargetException
const & )
2807 OSL_FAIL( "Content::flushData - Error!" );
2811 //=========================================================================
2812 uno::Reference
< io::XInputStream
> Content::getInputStream()
2814 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2816 uno::Reference
< io::XInputStream
> xStream
;
2817 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2821 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2826 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2827 uno::Reference
< io::XActiveDataSink
> xSink
;
2832 OSL_FAIL( "Content::getInputStream - "
2833 "Got no XActiveDataSink interface!" );
2837 xStream
= xSink
->getInputStream();
2839 OSL_ENSURE( xStream
.is(),
2840 "Content::getInputStream - Got no stream!" );
2842 catch ( container::NoSuchElementException
const & )
2844 // getByHierarchicalName
2850 //=========================================================================
2851 uno::Reference
< container::XEnumeration
> Content::getIterator()
2853 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2855 uno::Reference
< container::XEnumeration
> xIter
;
2856 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2860 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2865 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2866 uno::Reference
< container::XEnumerationAccess
> xIterFac
;
2867 aEntry
>>= xIterFac
;
2869 if ( !xIterFac
.is() )
2871 OSL_FAIL( "Content::getIterator - "
2872 "Got no XEnumerationAccess interface!" );
2876 xIter
= xIterFac
->createEnumeration();
2878 OSL_ENSURE( xIter
.is(),
2879 "Content::getIterator - Got no iterator!" );
2881 catch ( container::NoSuchElementException
const & )
2883 // getByHierarchicalName
2889 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */