1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pkgcontent.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 /**************************************************************************
36 **************************************************************************
37 *************************************************************************/
38 #include <osl/diagnose.h>
40 #include "osl/doublecheckedlocking.h"
41 #include <rtl/ustring.h>
42 #include <rtl/ustring.hxx>
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <com/sun/star/beans/PropertyState.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/beans/XPropertyAccess.hpp>
47 #include <com/sun/star/container/XEnumerationAccess.hpp>
48 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
49 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <com/sun/star/container/XNamed.hpp>
51 #include <com/sun/star/io/XActiveDataSink.hpp>
52 #include <com/sun/star/io/XInputStream.hpp>
53 #include <com/sun/star/io/XOutputStream.hpp>
54 #include <com/sun/star/lang/IllegalAccessException.hpp>
55 #include <com/sun/star/sdbc/XRow.hpp>
56 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
57 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
58 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
59 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
61 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
62 #include <com/sun/star/ucb/NameClash.hpp>
63 #include <com/sun/star/ucb/NameClashException.hpp>
64 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
65 #include <com/sun/star/ucb/OpenMode.hpp>
66 #include <com/sun/star/ucb/TransferInfo.hpp>
67 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
68 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
69 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
70 #include <com/sun/star/ucb/XCommandInfo.hpp>
71 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
72 #include <com/sun/star/util/XChangesBatch.hpp>
73 #include <com/sun/star/uno/Any.hxx>
74 #include <com/sun/star/uno/Sequence.hxx>
75 #include <ucbhelper/contentidentifier.hxx>
76 #include <ucbhelper/propertyvalueset.hxx>
77 #include <ucbhelper/cancelcommandexecution.hxx>
78 #include "pkgcontent.hxx"
79 #include "pkgprovider.hxx"
80 #include "pkgresultset.hxx"
82 #include "../inc/urihelper.hxx"
84 using namespace com::sun::star
;
85 using namespace package_ucp
;
87 #define NONE_MODIFIED sal_uInt32( 0x00 )
88 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
89 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
90 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
91 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
93 //=========================================================================
94 //=========================================================================
96 // ContentProperties Implementation.
98 //=========================================================================
99 //=========================================================================
101 ContentProperties::ContentProperties( const rtl::OUString
& rContentType
)
102 : aContentType( rContentType
),
104 bCompressed( sal_True
),
105 bEncrypted( sal_False
),
106 bHasEncryptedEntries( sal_False
)
108 bIsFolder
= rContentType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PACKAGE_FOLDER_CONTENT_TYPE
) )
109 || rContentType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_FOLDER_CONTENT_TYPE
) );
110 bIsDocument
= !bIsFolder
;
112 OSL_ENSURE( bIsFolder
||
113 rContentType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PACKAGE_STREAM_CONTENT_TYPE
) ) ||
114 rContentType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_STREAM_CONTENT_TYPE
) ),
115 "ContentProperties::ContentProperties - Unknown type!" );
118 //=========================================================================
119 //=========================================================================
121 // Content Implementation.
123 //=========================================================================
124 //=========================================================================
126 // static ( "virtual" ctor )
127 Content
* Content::create(
128 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
129 ContentProvider
* pProvider
,
130 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
132 rtl::OUString aURL
= Identifier
->getContentIdentifier();
133 PackageUri
aURI( aURL
);
134 ContentProperties aProps
;
135 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
137 if ( loadData( pProvider
, aURI
, aProps
, xPackage
) )
141 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
142 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
144 // Client explicitely requested a folder!
145 if ( !aProps
.bIsFolder
)
149 uno::Reference
< ucb::XContentIdentifier
> xId
150 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
151 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, aProps
);
155 // resource doesn't exist
157 sal_Bool bFolder
= sal_False
;
159 // Guess type according to URI.
160 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
161 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
164 uno::Reference
< ucb::XContentIdentifier
> xId
165 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
167 ucb::ContentInfo aInfo
;
168 if ( bFolder
|| aURI
.isRootFolder() )
169 aInfo
.Type
= GetContentType( aURI
.getScheme(), sal_True
);
171 aInfo
.Type
= GetContentType( aURI
.getScheme(), sal_False
);
173 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, aInfo
);
177 //=========================================================================
178 // static ( "virtual" ctor )
179 Content
* Content::create(
180 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
181 ContentProvider
* pProvider
,
182 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
183 const ucb::ContentInfo
& Info
)
185 if ( !Info
.Type
.getLength() )
188 PackageUri
aURI( Identifier
->getContentIdentifier() );
190 if ( !Info
.Type
.equalsIgnoreAsciiCase(
191 GetContentType( aURI
.getScheme(), sal_True
) ) &&
192 !Info
.Type
.equalsIgnoreAsciiCase(
193 GetContentType( aURI
.getScheme(), sal_False
) ) )
196 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
199 // Fail, if content does exist.
200 if ( hasData( pProvider
, aURI
, xPackage
) )
203 xPackage
= pProvider
->createPackage( aURI
.getPackage(), aURI
.getParam() );
206 uno::Reference
< ucb::XContentIdentifier
> xId
207 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
208 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, Info
);
211 //=========================================================================
213 ::rtl::OUString
Content::GetContentType(
214 const ::rtl::OUString
& aScheme
, sal_Bool bFolder
)
216 return ( rtl::OUString::createFromAscii( "application/" )
219 ? rtl::OUString::createFromAscii( "-folder" )
220 : rtl::OUString::createFromAscii( "-stream" ) ) );
223 //=========================================================================
225 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
226 ContentProvider
* pProvider
,
227 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
228 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
229 const PackageUri
& rUri
,
230 const ContentProperties
& rProps
)
231 : ContentImplHelper( rxSMgr
, pProvider
, Identifier
),
234 m_eState( PERSISTENT
),
235 m_xPackage( Package
),
236 m_pProvider( pProvider
),
237 m_nModifiedProps( NONE_MODIFIED
)
241 //=========================================================================
243 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
244 ContentProvider
* pProvider
,
245 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
246 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
247 const PackageUri
& rUri
,
248 const ucb::ContentInfo
& Info
)
249 : ContentImplHelper( rxSMgr
, pProvider
, Identifier
),
251 m_aProps( Info
.Type
),
252 m_eState( TRANSIENT
),
253 m_xPackage( Package
),
254 m_pProvider( pProvider
),
255 m_nModifiedProps( NONE_MODIFIED
)
259 //=========================================================================
265 //=========================================================================
267 // XInterface methods.
269 //=========================================================================
272 void SAL_CALL
Content::acquire()
275 ContentImplHelper::acquire();
278 //=========================================================================
280 void SAL_CALL
Content::release()
283 ContentImplHelper::release();
286 //=========================================================================
288 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
)
289 throw ( uno::RuntimeException
)
294 aRet
= cppu::queryInterface(
295 rType
, static_cast< ucb::XContentCreator
* >( this ) );
297 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface( rType
);
300 //=========================================================================
302 // XTypeProvider methods.
304 //=========================================================================
306 XTYPEPROVIDER_COMMON_IMPL( Content
);
308 //=========================================================================
310 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
311 throw( uno::RuntimeException
)
313 cppu::OTypeCollection
* pCollection
= 0;
317 static cppu::OTypeCollection
* pFolderTypes
= 0;
319 pCollection
= pFolderTypes
;
322 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
324 pCollection
= pFolderTypes
;
327 static cppu::OTypeCollection
aCollection(
328 CPPU_TYPE_REF( lang::XTypeProvider
),
329 CPPU_TYPE_REF( lang::XServiceInfo
),
330 CPPU_TYPE_REF( lang::XComponent
),
331 CPPU_TYPE_REF( ucb::XContent
),
332 CPPU_TYPE_REF( ucb::XCommandProcessor
),
333 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
334 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
335 CPPU_TYPE_REF( beans::XPropertyContainer
),
336 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
337 CPPU_TYPE_REF( container::XChild
),
338 CPPU_TYPE_REF( ucb::XContentCreator
) ); // !!
339 pCollection
= &aCollection
;
340 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
341 pFolderTypes
= pCollection
;
345 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
350 static cppu::OTypeCollection
* pDocumentTypes
= 0;
352 pCollection
= pDocumentTypes
;
355 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
357 pCollection
= pDocumentTypes
;
360 static cppu::OTypeCollection
aCollection(
361 CPPU_TYPE_REF( lang::XTypeProvider
),
362 CPPU_TYPE_REF( lang::XServiceInfo
),
363 CPPU_TYPE_REF( lang::XComponent
),
364 CPPU_TYPE_REF( ucb::XContent
),
365 CPPU_TYPE_REF( ucb::XCommandProcessor
),
366 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
367 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
368 CPPU_TYPE_REF( beans::XPropertyContainer
),
369 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
370 CPPU_TYPE_REF( container::XChild
) );
371 pCollection
= &aCollection
;
372 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
373 pDocumentTypes
= pCollection
;
377 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
381 return (*pCollection
).getTypes();
384 //=========================================================================
386 // XServiceInfo methods.
388 //=========================================================================
391 rtl::OUString SAL_CALL
Content::getImplementationName()
392 throw( uno::RuntimeException
)
394 return rtl::OUString::createFromAscii(
395 "com.sun.star.comp.ucb.PackageContent" );
398 //=========================================================================
400 uno::Sequence
< rtl::OUString
> SAL_CALL
Content::getSupportedServiceNames()
401 throw( uno::RuntimeException
)
403 uno::Sequence
< rtl::OUString
> aSNS( 1 );
406 = rtl::OUString::createFromAscii(
407 PACKAGE_FOLDER_CONTENT_SERVICE_NAME
);
410 = rtl::OUString::createFromAscii(
411 PACKAGE_STREAM_CONTENT_SERVICE_NAME
);
416 //=========================================================================
420 //=========================================================================
423 rtl::OUString SAL_CALL
Content::getContentType()
424 throw( uno::RuntimeException
)
426 return m_aProps
.aContentType
;
429 //=========================================================================
431 // XCommandProcessor methods.
433 //=========================================================================
436 uno::Any SAL_CALL
Content::execute(
437 const ucb::Command
& aCommand
,
438 sal_Int32
/*CommandId*/,
439 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
440 throw( uno::Exception
,
441 ucb::CommandAbortedException
,
442 uno::RuntimeException
)
446 if ( aCommand
.Name
.equalsAsciiL(
447 RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
449 //////////////////////////////////////////////////////////////////
451 //////////////////////////////////////////////////////////////////
453 uno::Sequence
< beans::Property
> Properties
;
454 if ( !( aCommand
.Argument
>>= Properties
) )
456 ucbhelper::cancelCommandExecution(
457 uno::makeAny( lang::IllegalArgumentException(
458 rtl::OUString::createFromAscii(
459 "Wrong argument type!" ),
460 static_cast< cppu::OWeakObject
* >( this ),
466 aRet
<<= getPropertyValues( Properties
);
468 else if ( aCommand
.Name
.equalsAsciiL(
469 RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
471 //////////////////////////////////////////////////////////////////
473 //////////////////////////////////////////////////////////////////
475 uno::Sequence
< beans::PropertyValue
> aProperties
;
476 if ( !( aCommand
.Argument
>>= aProperties
) )
478 ucbhelper::cancelCommandExecution(
479 uno::makeAny( lang::IllegalArgumentException(
480 rtl::OUString::createFromAscii(
481 "Wrong argument type!" ),
482 static_cast< cppu::OWeakObject
* >( this ),
488 if ( !aProperties
.getLength() )
490 ucbhelper::cancelCommandExecution(
491 uno::makeAny( lang::IllegalArgumentException(
492 rtl::OUString::createFromAscii(
494 static_cast< cppu::OWeakObject
* >( this ),
500 aRet
<<= setPropertyValues( aProperties
, Environment
);
502 else if ( aCommand
.Name
.equalsAsciiL(
503 RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
505 //////////////////////////////////////////////////////////////////
506 // getPropertySetInfo
507 //////////////////////////////////////////////////////////////////
509 // Note: Implemented by base class.
510 aRet
<<= getPropertySetInfo( Environment
);
512 else if ( aCommand
.Name
.equalsAsciiL(
513 RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
515 //////////////////////////////////////////////////////////////////
517 //////////////////////////////////////////////////////////////////
519 // Note: Implemented by base class.
520 aRet
<<= getCommandInfo( Environment
);
522 else if ( aCommand
.Name
.equalsAsciiL(
523 RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
525 //////////////////////////////////////////////////////////////////
527 //////////////////////////////////////////////////////////////////
529 ucb::OpenCommandArgument2 aOpenCommand
;
530 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
532 ucbhelper::cancelCommandExecution(
533 uno::makeAny( lang::IllegalArgumentException(
534 rtl::OUString::createFromAscii(
535 "Wrong argument type!" ),
536 static_cast< cppu::OWeakObject
* >( this ),
542 aRet
= open( aOpenCommand
, Environment
);
544 else if ( !m_aUri
.isRootFolder()
545 && aCommand
.Name
.equalsAsciiL(
546 RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
548 //////////////////////////////////////////////////////////////////
550 //////////////////////////////////////////////////////////////////
552 ucb::InsertCommandArgument aArg
;
553 if ( !( aCommand
.Argument
>>= aArg
) )
555 ucbhelper::cancelCommandExecution(
556 uno::makeAny( lang::IllegalArgumentException(
557 rtl::OUString::createFromAscii(
558 "Wrong argument type!" ),
559 static_cast< cppu::OWeakObject
* >( this ),
565 sal_Int32 nNameClash
= aArg
.ReplaceExisting
566 ? ucb::NameClash::OVERWRITE
567 : ucb::NameClash::ERROR
;
568 insert( aArg
.Data
, nNameClash
, Environment
);
570 else if ( !m_aUri
.isRootFolder()
571 && aCommand
.Name
.equalsAsciiL(
572 RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
574 //////////////////////////////////////////////////////////////////
576 //////////////////////////////////////////////////////////////////
578 sal_Bool bDeletePhysical
= sal_False
;
579 aCommand
.Argument
>>= bDeletePhysical
;
580 destroy( bDeletePhysical
, Environment
);
582 // Remove own and all children's persistent data.
587 beans::PropertyValue(
588 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
591 uno::makeAny(m_xIdentifier
->
592 getContentIdentifier()),
593 beans::PropertyState_DIRECT_VALUE
));
594 ucbhelper::cancelCommandExecution(
595 ucb::IOErrorCode_CANT_WRITE
,
596 uno::Sequence
< uno::Any
>(&aProps
, 1),
598 rtl::OUString::createFromAscii(
599 "Cannot remove persistent data!" ),
604 // Remove own and all children's Additional Core Properties.
605 removeAdditionalPropertySet( sal_True
);
607 else if ( aCommand
.Name
.equalsAsciiL(
608 RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) )
610 //////////////////////////////////////////////////////////////////
612 // ( Not available at stream objects )
613 //////////////////////////////////////////////////////////////////
615 ucb::TransferInfo aInfo
;
616 if ( !( aCommand
.Argument
>>= aInfo
) )
618 ucbhelper::cancelCommandExecution(
619 uno::makeAny( lang::IllegalArgumentException(
620 rtl::OUString::createFromAscii(
621 "Wrong argument type!" ),
622 static_cast< cppu::OWeakObject
* >( this ),
628 transfer( aInfo
, Environment
);
630 else if ( aCommand
.Name
.equalsAsciiL(
631 RTL_CONSTASCII_STRINGPARAM( "flush" ) ) )
633 //////////////////////////////////////////////////////////////////
635 // ( Not available at stream objects )
636 //////////////////////////////////////////////////////////////////
642 beans::PropertyValue(
643 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
646 uno::makeAny(m_xIdentifier
->
647 getContentIdentifier()),
648 beans::PropertyState_DIRECT_VALUE
));
649 ucbhelper::cancelCommandExecution(
650 ucb::IOErrorCode_CANT_WRITE
,
651 uno::Sequence
< uno::Any
>(&aProps
, 1),
653 rtl::OUString::createFromAscii(
654 "Cannot write file to disk!" ),
661 //////////////////////////////////////////////////////////////////
662 // Unsupported command
663 //////////////////////////////////////////////////////////////////
665 ucbhelper::cancelCommandExecution(
666 uno::makeAny( ucb::UnsupportedCommandException(
668 static_cast< cppu::OWeakObject
* >( this ) ) ),
676 //=========================================================================
678 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
679 throw( uno::RuntimeException
)
681 // @@@ Implement logic to abort running commands, if this makes
682 // sense for your content.
685 //=========================================================================
687 // XContentCreator methods.
689 //=========================================================================
692 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
693 Content::queryCreatableContentsInfo()
694 throw( uno::RuntimeException
)
698 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
700 uno::Sequence
< beans::Property
> aProps( 1 );
701 aProps
.getArray()[ 0 ] = beans::Property(
702 rtl::OUString::createFromAscii( "Title" ),
704 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
705 beans::PropertyAttribute::BOUND
);
707 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
710 aSeq
.getArray()[ 0 ].Type
711 = GetContentType( m_aUri
.getScheme(), sal_True
);
712 aSeq
.getArray()[ 0 ].Attributes
713 = ucb::ContentInfoAttribute::KIND_FOLDER
;
714 aSeq
.getArray()[ 0 ].Properties
= aProps
;
717 aSeq
.getArray()[ 1 ].Type
718 = GetContentType( m_aUri
.getScheme(), sal_False
);
719 aSeq
.getArray()[ 1 ].Attributes
720 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
721 | ucb::ContentInfoAttribute::KIND_DOCUMENT
;
722 aSeq
.getArray()[ 1 ].Properties
= aProps
;
728 OSL_ENSURE( sal_False
,
729 "queryCreatableContentsInfo called on non-folder object!" );
731 return uno::Sequence
< ucb::ContentInfo
>( 0 );
735 //=========================================================================
737 uno::Reference
< ucb::XContent
> SAL_CALL
738 Content::createNewContent( const ucb::ContentInfo
& Info
)
739 throw( uno::RuntimeException
)
743 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
745 if ( !Info
.Type
.getLength() )
746 return uno::Reference
< ucb::XContent
>();
748 if ( !Info
.Type
.equalsIgnoreAsciiCase(
749 GetContentType( m_aUri
.getScheme(), sal_True
) ) &&
750 !Info
.Type
.equalsIgnoreAsciiCase(
751 GetContentType( m_aUri
.getScheme(), sal_False
) ) )
752 return uno::Reference
< ucb::XContent
>();
754 rtl::OUString aURL
= m_aUri
.getUri();
755 aURL
+= rtl::OUString::createFromAscii( "/" );
757 if ( Info
.Type
.equalsIgnoreAsciiCase(
758 GetContentType( m_aUri
.getScheme(), sal_True
) ) )
759 aURL
+= rtl::OUString::createFromAscii( "New_Folder" );
761 aURL
+= rtl::OUString::createFromAscii( "New_Stream" );
763 uno::Reference
< ucb::XContentIdentifier
> xId(
764 new ::ucbhelper::ContentIdentifier( m_xSMgr
, aURL
) );
766 return create( m_xSMgr
, m_pProvider
, xId
, Info
);
770 OSL_ENSURE( sal_False
,
771 "createNewContent called on non-folder object!" );
772 return uno::Reference
< ucb::XContent
>();
776 //=========================================================================
778 // Non-interface methods.
780 //=========================================================================
783 rtl::OUString
Content::getParentURL()
785 return m_aUri
.getParentUri();
788 //=========================================================================
790 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
791 const uno::Reference
< lang::XMultiServiceFactory
>& rSMgr
,
792 const uno::Sequence
< beans::Property
>& rProperties
,
793 ContentProvider
* pProvider
,
794 const rtl::OUString
& rContentId
)
796 ContentProperties aData
;
797 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
798 if ( loadData( pProvider
, PackageUri( rContentId
), aData
, xPackage
) )
800 return getPropertyValues( rSMgr
,
804 ::ucbhelper::ContentProviderImplHelper
>(
810 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
811 = new ::ucbhelper::PropertyValueSet( rSMgr
);
813 sal_Int32 nCount
= rProperties
.getLength();
816 const beans::Property
* pProps
= rProperties
.getConstArray();
817 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
818 xRow
->appendVoid( pProps
[ n
] );
821 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
825 //=========================================================================
827 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
828 const uno::Reference
< lang::XMultiServiceFactory
>& rSMgr
,
829 const uno::Sequence
< beans::Property
>& rProperties
,
830 const ContentProperties
& rData
,
831 const rtl::Reference
< ::ucbhelper::ContentProviderImplHelper
>&
833 const rtl::OUString
& rContentId
)
835 // Note: Empty sequence means "get values of all supported properties".
837 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
838 = new ::ucbhelper::PropertyValueSet( rSMgr
);
840 sal_Int32 nCount
= rProperties
.getLength();
843 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
844 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
846 const beans::Property
* pProps
= rProperties
.getConstArray();
847 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
849 const beans::Property
& rProp
= pProps
[ n
];
851 // Process Core properties.
853 if ( rProp
.Name
.equalsAsciiL(
854 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
856 xRow
->appendString ( rProp
, rData
.aContentType
);
858 else if ( rProp
.Name
.equalsAsciiL(
859 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
861 xRow
->appendString ( rProp
, rData
.aTitle
);
863 else if ( rProp
.Name
.equalsAsciiL(
864 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
866 xRow
->appendBoolean( rProp
, rData
.bIsDocument
);
868 else if ( rProp
.Name
.equalsAsciiL(
869 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
871 xRow
->appendBoolean( rProp
, rData
.bIsFolder
);
873 else if ( rProp
.Name
.equalsAsciiL(
874 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
876 xRow
->appendString ( rProp
, rData
.aMediaType
);
878 else if ( rProp
.Name
.equalsAsciiL(
879 RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
881 // Property only available for streams.
882 if ( rData
.bIsDocument
)
883 xRow
->appendLong( rProp
, rData
.nSize
);
885 xRow
->appendVoid( rProp
);
887 else if ( rProp
.Name
.equalsAsciiL(
888 RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) )
890 // Property only available for streams.
891 if ( rData
.bIsDocument
)
892 xRow
->appendBoolean( rProp
, rData
.bCompressed
);
894 xRow
->appendVoid( rProp
);
896 else if ( rProp
.Name
.equalsAsciiL(
897 RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) )
899 // Property only available for streams.
900 if ( rData
.bIsDocument
)
901 xRow
->appendBoolean( rProp
, rData
.bEncrypted
);
903 xRow
->appendVoid( rProp
);
905 else if ( rProp
.Name
.equalsAsciiL(
906 RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) )
908 // Property only available for root folder.
909 PackageUri
aURI( rContentId
);
910 if ( aURI
.isRootFolder() )
911 xRow
->appendBoolean( rProp
, rData
.bHasEncryptedEntries
);
913 xRow
->appendVoid( rProp
);
917 // Not a Core Property! Maybe it's an Additional Core Property?!
919 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
922 = uno::Reference
< beans::XPropertySet
>(
923 rProvider
->getAdditionalPropertySet( rContentId
,
926 bTriedToGetAdditonalPropSet
= sal_True
;
929 if ( xAdditionalPropSet
.is() )
931 if ( !xRow
->appendPropertySetValue(
935 // Append empty entry.
936 xRow
->appendVoid( rProp
);
941 // Append empty entry.
942 xRow
->appendVoid( rProp
);
949 // Append all Core Properties.
952 rtl::OUString::createFromAscii( "ContentType" ),
954 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
955 beans::PropertyAttribute::BOUND
956 | beans::PropertyAttribute::READONLY
),
957 rData
.aContentType
);
960 rtl::OUString::createFromAscii( "Title" ),
962 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
963 beans::PropertyAttribute::BOUND
),
967 rtl::OUString::createFromAscii( "IsDocument" ),
969 getCppuBooleanType(),
970 beans::PropertyAttribute::BOUND
971 | beans::PropertyAttribute::READONLY
),
975 rtl::OUString::createFromAscii( "IsFolder" ),
977 getCppuBooleanType(),
978 beans::PropertyAttribute::BOUND
979 | beans::PropertyAttribute::READONLY
),
983 rtl::OUString::createFromAscii( "MediaType" ),
985 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
986 beans::PropertyAttribute::BOUND
),
989 // Properties only available for streams.
990 if ( rData
.bIsDocument
)
994 rtl::OUString::createFromAscii( "Size" ),
996 getCppuType( static_cast< const sal_Int64
* >( 0 ) ),
997 beans::PropertyAttribute::BOUND
998 | beans::PropertyAttribute::READONLY
),
1001 xRow
->appendBoolean(
1003 rtl::OUString::createFromAscii( "Compressed" ),
1005 getCppuBooleanType(),
1006 beans::PropertyAttribute::BOUND
),
1007 rData
.bCompressed
);
1009 xRow
->appendBoolean(
1011 rtl::OUString::createFromAscii( "Encrypted" ),
1013 getCppuBooleanType(),
1014 beans::PropertyAttribute::BOUND
),
1018 // Properties only available for root folder.
1019 PackageUri
aURI( rContentId
);
1020 if ( aURI
.isRootFolder() )
1022 xRow
->appendBoolean(
1024 rtl::OUString::createFromAscii( "HasEncryptedEntries" ),
1026 getCppuBooleanType(),
1027 beans::PropertyAttribute::BOUND
1028 | beans::PropertyAttribute::READONLY
),
1029 rData
.bHasEncryptedEntries
);
1032 // Append all Additional Core Properties.
1034 uno::Reference
< beans::XPropertySet
> xSet(
1035 rProvider
->getAdditionalPropertySet( rContentId
, sal_False
),
1037 xRow
->appendPropertySet( xSet
);
1040 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
1043 //=========================================================================
1044 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
1045 const uno::Sequence
< beans::Property
>& rProperties
)
1047 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1048 return getPropertyValues( m_xSMgr
,
1052 ::ucbhelper::ContentProviderImplHelper
>(
1053 m_xProvider
.get() ),
1054 m_xIdentifier
->getContentIdentifier() );
1057 //=========================================================================
1058 uno::Sequence
< uno::Any
> Content::setPropertyValues(
1059 const uno::Sequence
< beans::PropertyValue
>& rValues
,
1060 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1061 throw( uno::Exception
)
1063 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1065 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
1066 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
1067 sal_Int32 nChanged
= 0;
1069 beans::PropertyChangeEvent aEvent
;
1070 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
1071 aEvent
.Further
= sal_False
;
1072 // aEvent.PropertyName =
1073 aEvent
.PropertyHandle
= -1;
1074 // aEvent.OldValue =
1075 // aEvent.NewValue =
1077 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1078 sal_Int32 nCount
= rValues
.getLength();
1080 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1081 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
1082 sal_Bool bExchange
= sal_False
;
1083 sal_Bool bStore
= sal_False
;
1084 rtl::OUString aNewTitle
;
1085 sal_Int32 nTitlePos
= -1;
1087 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1089 const beans::PropertyValue
& rValue
= pValues
[ n
];
1091 if ( rValue
.Name
.equalsAsciiL(
1092 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
1094 // Read-only property!
1095 aRet
[ n
] <<= lang::IllegalAccessException(
1096 rtl::OUString::createFromAscii(
1097 "Property is read-only!" ),
1098 static_cast< cppu::OWeakObject
* >( this ) );
1100 else if ( rValue
.Name
.equalsAsciiL(
1101 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
1103 // Read-only property!
1104 aRet
[ n
] <<= lang::IllegalAccessException(
1105 rtl::OUString::createFromAscii(
1106 "Property is read-only!" ),
1107 static_cast< cppu::OWeakObject
* >( this ) );
1109 else if ( rValue
.Name
.equalsAsciiL(
1110 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
1112 // Read-only property!
1113 aRet
[ n
] <<= lang::IllegalAccessException(
1114 rtl::OUString::createFromAscii(
1115 "Property is read-only!" ),
1116 static_cast< cppu::OWeakObject
* >( this ) );
1118 else if ( rValue
.Name
.equalsAsciiL(
1119 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
1121 if ( m_aUri
.isRootFolder() )
1123 // Read-only property!
1124 aRet
[ n
] <<= lang::IllegalAccessException(
1125 rtl::OUString::createFromAscii(
1126 "Property is read-only!" ),
1127 static_cast< cppu::OWeakObject
* >( this ) );
1131 rtl::OUString aNewValue
;
1132 if ( rValue
.Value
>>= aNewValue
)
1135 if ( aNewValue
.getLength() > 0 )
1137 if ( aNewValue
!= m_aProps
.aTitle
)
1139 // modified title -> modified URL -> exchange !
1140 if ( m_eState
== PERSISTENT
)
1141 bExchange
= sal_True
;
1143 // new value will be set later...
1144 aNewTitle
= aNewValue
;
1146 // remember position within sequence of values
1147 // (for error handling).
1154 lang::IllegalArgumentException(
1155 rtl::OUString::createFromAscii(
1156 "Empty title not allowed!" ),
1157 static_cast< cppu::OWeakObject
* >( this ),
1164 beans::IllegalTypeException(
1165 rtl::OUString::createFromAscii(
1166 "Property value has wrong type!" ),
1167 static_cast< cppu::OWeakObject
* >( this ) );
1171 else if ( rValue
.Name
.equalsAsciiL(
1172 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
1174 rtl::OUString aNewValue
;
1175 if ( rValue
.Value
>>= aNewValue
)
1177 if ( aNewValue
!= m_aProps
.aMediaType
)
1179 aEvent
.PropertyName
= rValue
.Name
;
1180 aEvent
.OldValue
= uno::makeAny( m_aProps
.aMediaType
);
1181 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1183 m_aProps
.aMediaType
= aNewValue
;
1186 m_nModifiedProps
|= MEDIATYPE_MODIFIED
;
1191 aRet
[ n
] <<= beans::IllegalTypeException(
1192 rtl::OUString::createFromAscii(
1193 "Property value has wrong type!" ),
1194 static_cast< cppu::OWeakObject
* >( this ) );
1197 else if ( rValue
.Name
.equalsAsciiL(
1198 RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
1200 // Read-only property!
1201 aRet
[ n
] <<= lang::IllegalAccessException(
1202 rtl::OUString::createFromAscii(
1203 "Property is read-only!" ),
1204 static_cast< cppu::OWeakObject
* >( this ) );
1206 else if ( rValue
.Name
.equalsAsciiL(
1207 RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) )
1209 // Property only available for streams.
1210 if ( m_aProps
.bIsDocument
)
1213 if ( rValue
.Value
>>= bNewValue
)
1215 if ( bNewValue
!= m_aProps
.bCompressed
)
1217 aEvent
.PropertyName
= rValue
.Name
;
1218 aEvent
.OldValue
= uno::makeAny( m_aProps
.bCompressed
);
1219 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1221 m_aProps
.bCompressed
= bNewValue
;
1224 m_nModifiedProps
|= COMPRESSED_MODIFIED
;
1229 aRet
[ n
] <<= beans::IllegalTypeException(
1230 rtl::OUString::createFromAscii(
1231 "Property value has wrong type!" ),
1232 static_cast< cppu::OWeakObject
* >( this ) );
1237 aRet
[ n
] <<= beans::UnknownPropertyException(
1238 rtl::OUString::createFromAscii(
1239 "Compressed only supported by streams!" ),
1240 static_cast< cppu::OWeakObject
* >( this ) );
1243 else if ( rValue
.Name
.equalsAsciiL(
1244 RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) )
1246 // Property only available for streams.
1247 if ( m_aProps
.bIsDocument
)
1250 if ( rValue
.Value
>>= bNewValue
)
1252 if ( bNewValue
!= m_aProps
.bEncrypted
)
1254 aEvent
.PropertyName
= rValue
.Name
;
1255 aEvent
.OldValue
= uno::makeAny( m_aProps
.bEncrypted
);
1256 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1258 m_aProps
.bEncrypted
= bNewValue
;
1261 m_nModifiedProps
|= ENCRYPTED_MODIFIED
;
1266 aRet
[ n
] <<= beans::IllegalTypeException(
1267 rtl::OUString::createFromAscii(
1268 "Property value has wrong type!" ),
1269 static_cast< cppu::OWeakObject
* >( this ) );
1274 aRet
[ n
] <<= beans::UnknownPropertyException(
1275 rtl::OUString::createFromAscii(
1276 "Encrypted only supported by streams!" ),
1277 static_cast< cppu::OWeakObject
* >( this ) );
1280 else if ( rValue
.Name
.equalsAsciiL(
1281 RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) )
1283 // Read-only property!
1284 aRet
[ n
] <<= lang::IllegalAccessException(
1285 rtl::OUString::createFromAscii(
1286 "Property is read-only!" ),
1287 static_cast< cppu::OWeakObject
* >( this ) );
1289 else if ( rValue
.Name
.equalsAsciiL(
1290 RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) )
1292 // @@@ This is a temporary solution. In the future submitting
1293 // the key should be done using an interaction handler!
1295 // Write-Only property. Only supported by root folder and streams
1296 // (all non-root folders of a package have the same encryption key).
1297 if ( m_aUri
.isRootFolder() || m_aProps
.bIsDocument
)
1299 uno::Sequence
< sal_Int8
> aNewValue
;
1300 if ( rValue
.Value
>>= aNewValue
)
1302 if ( aNewValue
!= m_aProps
.aEncryptionKey
)
1304 aEvent
.PropertyName
= rValue
.Name
;
1305 aEvent
.OldValue
= uno::makeAny(
1306 m_aProps
.aEncryptionKey
);
1307 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1309 m_aProps
.aEncryptionKey
= aNewValue
;
1312 m_nModifiedProps
|= ENCRYPTIONKEY_MODIFIED
;
1317 aRet
[ n
] <<= beans::IllegalTypeException(
1318 rtl::OUString::createFromAscii(
1319 "Property value has wrong type!" ),
1320 static_cast< cppu::OWeakObject
* >( this ) );
1325 aRet
[ n
] <<= beans::UnknownPropertyException(
1326 rtl::OUString::createFromAscii(
1327 "EncryptionKey not supported by non-root folder!" ),
1328 static_cast< cppu::OWeakObject
* >( this ) );
1333 // Not a Core Property! Maybe it's an Additional Core Property?!
1335 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
1337 xAdditionalPropSet
= getAdditionalPropertySet( sal_False
);
1338 bTriedToGetAdditonalPropSet
= sal_True
;
1341 if ( xAdditionalPropSet
.is() )
1346 = xAdditionalPropSet
->getPropertyValue( rValue
.Name
);
1347 if ( aOldValue
!= rValue
.Value
)
1349 xAdditionalPropSet
->setPropertyValue(
1350 rValue
.Name
, rValue
.Value
);
1352 aEvent
.PropertyName
= rValue
.Name
;
1353 aEvent
.OldValue
= aOldValue
;
1354 aEvent
.NewValue
= rValue
.Value
;
1356 aChanges
.getArray()[ nChanged
] = aEvent
;
1360 catch ( beans::UnknownPropertyException
const & e
)
1364 catch ( lang::WrappedTargetException
const & e
)
1368 catch ( beans::PropertyVetoException
const & e
)
1372 catch ( lang::IllegalArgumentException
const & e
)
1379 aRet
[ n
] <<= uno::Exception(
1380 rtl::OUString::createFromAscii(
1381 "No property set for storing the value!" ),
1382 static_cast< cppu::OWeakObject
* >( this ) );
1389 uno::Reference
< ucb::XContentIdentifier
> xOldId
= m_xIdentifier
;
1391 // Assemble new content identifier...
1392 rtl::OUString aNewURL
= m_aUri
.getParentUri();
1393 aNewURL
+= rtl::OUString::createFromAscii( "/" );
1394 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( aNewTitle
);
1395 uno::Reference
< ucb::XContentIdentifier
> xNewId
1396 = new ::ucbhelper::ContentIdentifier( m_xSMgr
, aNewURL
);
1399 if ( exchangeIdentity( xNewId
) )
1401 // Adapt persistent data.
1402 renameData( xOldId
, xNewId
);
1404 // Adapt Additional Core Properties.
1405 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1406 xNewId
->getContentIdentifier(),
1411 // Do not set new title!
1412 aNewTitle
= rtl::OUString();
1415 aRet
[ nTitlePos
] <<= uno::Exception(
1416 rtl::OUString::createFromAscii( "Exchange failed!" ),
1417 static_cast< cppu::OWeakObject
* >( this ) );
1421 if ( aNewTitle
.getLength() )
1423 aEvent
.PropertyName
= rtl::OUString::createFromAscii( "Title" );
1424 aEvent
.OldValue
= uno::makeAny( m_aProps
.aTitle
);
1425 aEvent
.NewValue
= uno::makeAny( aNewTitle
);
1427 m_aProps
.aTitle
= aNewTitle
;
1429 aChanges
.getArray()[ nChanged
] = aEvent
;
1435 // Save changes, if content was already made persistent.
1436 if ( ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
) ||
1437 ( bStore
&& ( m_eState
== PERSISTENT
) ) )
1439 if ( !storeData( uno::Reference
< io::XInputStream
>() ) )
1443 beans::PropertyValue(
1444 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1447 uno::makeAny(m_xIdentifier
->
1448 getContentIdentifier()),
1449 beans::PropertyState_DIRECT_VALUE
));
1450 ucbhelper::cancelCommandExecution(
1451 ucb::IOErrorCode_CANT_WRITE
,
1452 uno::Sequence
< uno::Any
>(&aProps
, 1),
1454 rtl::OUString::createFromAscii(
1455 "Cannot store persistent data!" ),
1462 aChanges
.realloc( nChanged
);
1463 notifyPropertiesChange( aChanges
);
1469 //=========================================================================
1470 uno::Any
Content::open(
1471 const ucb::OpenCommandArgument2
& rArg
,
1472 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1473 throw( uno::Exception
)
1475 if ( rArg
.Mode
== ucb::OpenMode::ALL
||
1476 rArg
.Mode
== ucb::OpenMode::FOLDERS
||
1477 rArg
.Mode
== ucb::OpenMode::DOCUMENTS
)
1479 //////////////////////////////////////////////////////////////////
1480 // open command for a folder content
1481 //////////////////////////////////////////////////////////////////
1483 uno::Reference
< ucb::XDynamicResultSet
> xSet
1484 = new DynamicResultSet( m_xSMgr
, this, rArg
, xEnv
);
1485 return uno::makeAny( xSet
);
1489 //////////////////////////////////////////////////////////////////
1490 // open command for a document content
1491 //////////////////////////////////////////////////////////////////
1493 if ( ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
1494 ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
) )
1496 // Currently(?) unsupported.
1497 ucbhelper::cancelCommandExecution(
1498 uno::makeAny( ucb::UnsupportedOpenModeException(
1500 static_cast< cppu::OWeakObject
* >( this ),
1501 sal_Int16( rArg
.Mode
) ) ),
1506 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
1507 uno::Reference
< io::XOutputStream
> xOut( rArg
.Sink
, uno::UNO_QUERY
);
1510 // PUSH: write data into xOut
1512 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1515 // No interaction if we are not persistent!
1518 beans::PropertyValue(
1519 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1522 uno::makeAny(m_xIdentifier
->
1523 getContentIdentifier()),
1524 beans::PropertyState_DIRECT_VALUE
));
1525 ucbhelper::cancelCommandExecution(
1526 ucb::IOErrorCode_CANT_READ
,
1527 uno::Sequence
< uno::Any
>(&aProps
, 1),
1528 m_eState
== PERSISTENT
1530 : uno::Reference
< ucb::XCommandEnvironment
>(),
1531 rtl::OUString::createFromAscii( "Got no data stream!" ),
1538 uno::Sequence
< sal_Int8
> aBuffer
;
1539 sal_Int32 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1543 aBuffer
.realloc( nRead
);
1544 xOut
->writeBytes( aBuffer
);
1545 aBuffer
.realloc( 0 );
1546 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1549 xOut
->closeOutput();
1551 catch ( io::NotConnectedException
const & )
1553 // closeOutput, readSomeBytes, writeBytes
1555 catch ( io::BufferSizeExceededException
const & )
1557 // closeOutput, readSomeBytes, writeBytes
1559 catch ( io::IOException
const & )
1561 // closeOutput, readSomeBytes, writeBytes
1566 uno::Reference
< io::XActiveDataSink
> xDataSink(
1567 rArg
.Sink
, uno::UNO_QUERY
);
1568 if ( xDataSink
.is() )
1570 // PULL: wait for client read
1572 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1575 // No interaction if we are not persistent!
1578 beans::PropertyValue(
1580 RTL_CONSTASCII_USTRINGPARAM("Uri")),
1582 uno::makeAny(m_xIdentifier
->
1583 getContentIdentifier()),
1584 beans::PropertyState_DIRECT_VALUE
));
1585 ucbhelper::cancelCommandExecution(
1586 ucb::IOErrorCode_CANT_READ
,
1587 uno::Sequence
< uno::Any
>(&aProps
, 1),
1588 m_eState
== PERSISTENT
1591 ucb::XCommandEnvironment
>(),
1592 rtl::OUString::createFromAscii(
1593 "Got no data stream!" ),
1599 xDataSink
->setInputStream( xIn
);
1603 // Note: aOpenCommand.Sink may contain an XStream
1604 // implementation. Support for this type of
1605 // sink is optional...
1606 ucbhelper::cancelCommandExecution(
1608 ucb::UnsupportedDataSinkException(
1610 static_cast< cppu::OWeakObject
* >( this ),
1621 //=========================================================================
1622 void Content::insert(
1623 const uno::Reference
< io::XInputStream
>& xStream
,
1624 sal_Int32 nNameClashResolve
,
1625 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1626 throw( uno::Exception
)
1628 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1630 // Check, if all required properties were set.
1635 if ( !m_aProps
.aTitle
.getLength() )
1636 m_aProps
.aTitle
= m_aUri
.getName();
1640 // Required: rArg.Data
1642 if ( !xStream
.is() )
1644 ucbhelper::cancelCommandExecution(
1645 uno::makeAny( ucb::MissingInputStreamException(
1647 static_cast< cppu::OWeakObject
* >( this ) ) ),
1654 if ( !m_aProps
.aTitle
.getLength() )
1655 m_aProps
.aTitle
= m_aUri
.getName();
1658 rtl::OUString aNewURL
= m_aUri
.getParentUri();
1659 if (1 + aNewURL
.lastIndexOf('/') != aNewURL
.getLength())
1660 aNewURL
+= rtl::OUString::createFromAscii( "/" );
1661 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( m_aProps
.aTitle
);
1662 PackageUri
aNewUri( aNewURL
);
1664 // Handle possible name clash...
1665 switch ( nNameClashResolve
)
1668 case ucb::NameClash::ERROR
:
1669 if ( hasData( aNewUri
) )
1671 ucbhelper::cancelCommandExecution(
1672 uno::makeAny( ucb::NameClashException(
1674 static_cast< cppu::OWeakObject
* >( this ),
1675 task::InteractionClassification_ERROR
,
1676 m_aProps
.aTitle
) ),
1682 // replace (possibly) existing object.
1683 case ucb::NameClash::OVERWRITE
:
1686 // "invent" a new valid title.
1687 case ucb::NameClash::RENAME
:
1688 if ( hasData( aNewUri
) )
1694 rtl::OUString aNew
= aNewUri
.getUri();
1695 aNew
+= rtl::OUString::createFromAscii( "_" );
1696 aNew
+= rtl::OUString::valueOf( ++nTry
);
1697 aNewUri
.setUri( aNew
);
1699 while ( hasData( aNewUri
) && ( nTry
< 1000 ) );
1703 ucbhelper::cancelCommandExecution(
1705 ucb::UnsupportedNameClashException(
1706 rtl::OUString::createFromAscii(
1707 "Unable to resolve name clash!" ),
1708 static_cast< cppu::OWeakObject
* >( this ),
1709 nNameClashResolve
) ),
1715 m_aProps
.aTitle
+= rtl::OUString::createFromAscii( "_" );
1716 m_aProps
.aTitle
+= rtl::OUString::valueOf( nTry
);
1721 case ucb::NameClash::KEEP
: // deprecated
1722 case ucb::NameClash::ASK
:
1724 if ( hasData( aNewUri
) )
1726 ucbhelper::cancelCommandExecution(
1728 ucb::UnsupportedNameClashException(
1730 static_cast< cppu::OWeakObject
* >( this ),
1731 nNameClashResolve
) ),
1738 // Identifier changed?
1739 sal_Bool bNewId
= ( m_aUri
.getUri() != aNewUri
.getUri() );
1743 m_xIdentifier
= new ::ucbhelper::ContentIdentifier( m_xSMgr
, aNewURL
);
1747 if ( !storeData( xStream
) )
1750 = uno::makeAny(beans::PropertyValue(
1751 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1754 uno::makeAny(m_xIdentifier
->
1755 getContentIdentifier()),
1756 beans::PropertyState_DIRECT_VALUE
));
1757 ucbhelper::cancelCommandExecution(
1758 ucb::IOErrorCode_CANT_WRITE
,
1759 uno::Sequence
< uno::Any
>(&aProps
, 1),
1761 rtl::OUString::createFromAscii( "Cannot store persistent data!" ),
1766 m_eState
= PERSISTENT
;
1770 // Take over correct default values from underlying packager...
1771 uno::Reference
< container::XHierarchicalNameAccess
> xXHierarchicalNameAccess
;
1772 loadData( m_pProvider
,
1775 xXHierarchicalNameAccess
);
1782 //=========================================================================
1783 void Content::destroy(
1784 sal_Bool bDeletePhysical
,
1785 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1786 throw( uno::Exception
)
1788 // @@@ take care about bDeletePhysical -> trashcan support
1790 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1792 uno::Reference
< ucb::XContent
> xThis
= this;
1795 if ( m_eState
!= PERSISTENT
)
1797 ucbhelper::cancelCommandExecution(
1798 uno::makeAny( ucb::UnsupportedCommandException(
1799 rtl::OUString::createFromAscii(
1800 "Not persistent!" ),
1801 static_cast< cppu::OWeakObject
* >( this ) ) ),
1813 // Process instanciated children...
1815 ContentRefList aChildren
;
1816 queryChildren( aChildren
);
1818 ContentRefList::const_iterator it
= aChildren
.begin();
1819 ContentRefList::const_iterator end
= aChildren
.end();
1823 (*it
)->destroy( bDeletePhysical
, xEnv
);
1829 //=========================================================================
1830 void Content::transfer(
1831 const ucb::TransferInfo
& rInfo
,
1832 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1833 throw( uno::Exception
)
1835 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1838 if ( m_eState
!= PERSISTENT
)
1840 ucbhelper::cancelCommandExecution(
1841 uno::makeAny( ucb::UnsupportedCommandException(
1842 rtl::OUString::createFromAscii(
1843 "Not persistent!" ),
1844 static_cast< cppu::OWeakObject
* >( this ) ) ),
1849 // Is source a package content?
1850 if ( ( rInfo
.SourceURL
.getLength() == 0 ) ||
1851 ( rInfo
.SourceURL
.compareTo(
1852 m_aUri
.getUri(), PACKAGE_URL_SCHEME_LENGTH
+ 3 ) != 0 ) )
1854 ucbhelper::cancelCommandExecution(
1855 uno::makeAny( ucb::InteractiveBadTransferURLException(
1857 static_cast< cppu::OWeakObject
* >( this ) ) ),
1862 // Is source not a parent of me / not me?
1863 rtl::OUString aId
= m_aUri
.getParentUri();
1864 aId
+= rtl::OUString::createFromAscii( "/" );
1866 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1869 rInfo
.SourceURL
, rInfo
.SourceURL
.getLength() ) == 0 )
1872 = uno::makeAny(beans::PropertyValue(
1874 RTL_CONSTASCII_USTRINGPARAM("Uri")),
1876 uno::makeAny(rInfo
.SourceURL
),
1877 beans::PropertyState_DIRECT_VALUE
));
1878 ucbhelper::cancelCommandExecution(
1879 ucb::IOErrorCode_RECURSIVE
,
1880 uno::Sequence
< uno::Any
>(&aProps
, 1),
1882 rtl::OUString::createFromAscii(
1883 "Target is equal to or is a child of source!" ),
1889 //////////////////////////////////////////////////////////////////////
1890 // 0) Obtain content object for source.
1891 //////////////////////////////////////////////////////////////////////
1893 uno::Reference
< ucb::XContentIdentifier
> xId
1894 = new ::ucbhelper::ContentIdentifier( m_xSMgr
, rInfo
.SourceURL
);
1896 // Note: The static cast is okay here, because its sure that
1897 // m_xProvider is always the PackageContentProvider.
1898 rtl::Reference
< Content
> xSource
;
1902 xSource
= static_cast< Content
* >(
1903 m_xProvider
->queryContent( xId
).get() );
1905 catch ( ucb::IllegalIdentifierException
const & )
1910 if ( !xSource
.is() )
1913 = uno::makeAny(beans::PropertyValue(
1914 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1917 uno::makeAny(xId
->getContentIdentifier()),
1918 beans::PropertyState_DIRECT_VALUE
));
1919 ucbhelper::cancelCommandExecution(
1920 ucb::IOErrorCode_CANT_READ
,
1921 uno::Sequence
< uno::Any
>(&aProps
, 1),
1923 rtl::OUString::createFromAscii(
1924 "Cannot instanciate source object!" ),
1929 //////////////////////////////////////////////////////////////////////
1930 // 1) Create new child content.
1931 //////////////////////////////////////////////////////////////////////
1933 rtl::OUString aType
= xSource
->isFolder()
1934 ? GetContentType( m_aUri
.getScheme(), sal_True
)
1935 : GetContentType( m_aUri
.getScheme(), sal_False
);
1936 ucb::ContentInfo aContentInfo
;
1937 aContentInfo
.Type
= aType
;
1938 aContentInfo
.Attributes
= 0;
1940 // Note: The static cast is okay here, because its sure that
1941 // createNewContent always creates a Content.
1942 rtl::Reference
< Content
> xTarget
1943 = static_cast< Content
* >( createNewContent( aContentInfo
).get() );
1944 if ( !xTarget
.is() )
1947 = uno::makeAny(beans::PropertyValue(
1948 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1952 beans::PropertyState_DIRECT_VALUE
));
1953 ucbhelper::cancelCommandExecution(
1954 ucb::IOErrorCode_CANT_CREATE
,
1955 uno::Sequence
< uno::Any
>(&aProps
, 1),
1957 rtl::OUString::createFromAscii(
1958 "XContentCreator::createNewContent failed!" ),
1963 //////////////////////////////////////////////////////////////////////
1964 // 2) Copy data from source content to child content.
1965 //////////////////////////////////////////////////////////////////////
1967 uno::Sequence
< beans::Property
> aSourceProps
1968 = xSource
->getPropertySetInfo( xEnv
)->getProperties();
1969 sal_Int32 nCount
= aSourceProps
.getLength();
1973 sal_Bool bHadTitle
= ( rInfo
.NewTitle
.getLength() == 0 );
1975 // Get all source values.
1976 uno::Reference
< sdbc::XRow
> xRow
1977 = xSource
->getPropertyValues( aSourceProps
);
1979 uno::Sequence
< beans::PropertyValue
> aValues( nCount
);
1980 beans::PropertyValue
* pValues
= aValues
.getArray();
1982 const beans::Property
* pProps
= aSourceProps
.getConstArray();
1983 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1985 const beans::Property
& rProp
= pProps
[ n
];
1986 beans::PropertyValue
& rValue
= pValues
[ n
];
1988 rValue
.Name
= rProp
.Name
;
1989 rValue
.Handle
= rProp
.Handle
;
1991 if ( !bHadTitle
&& rProp
.Name
.equalsAsciiL(
1992 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
1994 // Set new title instead of original.
1995 bHadTitle
= sal_True
;
1996 rValue
.Value
<<= rInfo
.NewTitle
;
2000 = xRow
->getObject( n
+ 1,
2002 container::XNameAccess
>() );
2004 rValue
.State
= beans::PropertyState_DIRECT_VALUE
;
2006 if ( rProp
.Attributes
& beans::PropertyAttribute::REMOVABLE
)
2008 // Add Additional Core Property.
2011 xTarget
->addProperty( rProp
.Name
,
2015 catch ( beans::PropertyExistException
const & )
2018 catch ( beans::IllegalTypeException
const & )
2021 catch ( lang::IllegalArgumentException
const & )
2027 // Set target values.
2028 xTarget
->setPropertyValues( aValues
, xEnv
);
2031 //////////////////////////////////////////////////////////////////////
2032 // 3) Commit (insert) child.
2033 //////////////////////////////////////////////////////////////////////
2035 xTarget
->insert( xSource
->getInputStream(), rInfo
.NameClash
, xEnv
);
2037 //////////////////////////////////////////////////////////////////////
2038 // 4) Transfer (copy) children of source.
2039 //////////////////////////////////////////////////////////////////////
2041 if ( xSource
->isFolder() )
2043 uno::Reference
< container::XEnumeration
> xIter
2044 = xSource
->getIterator();
2047 while ( xIter
->hasMoreElements() )
2051 uno::Reference
< container::XNamed
> xNamed
;
2052 xIter
->nextElement() >>= xNamed
;
2056 OSL_ENSURE( sal_False
,
2057 "Content::transfer - Got no XNamed!" );
2061 rtl::OUString aName
= xNamed
->getName();
2063 if ( !aName
.getLength() )
2065 OSL_ENSURE( sal_False
,
2066 "Content::transfer - Empty name!" );
2070 rtl::OUString aChildId
= xId
->getContentIdentifier();
2071 if ( ( aChildId
.lastIndexOf( '/' ) + 1 )
2072 != aChildId
.getLength() )
2073 aChildId
+= rtl::OUString::createFromAscii( "/" );
2075 aChildId
+= ::ucb_impl::urihelper::encodeSegment( aName
);
2077 ucb::TransferInfo aInfo
;
2078 aInfo
.MoveData
= sal_False
;
2079 aInfo
.NewTitle
= rtl::OUString();
2080 aInfo
.SourceURL
= aChildId
;
2081 aInfo
.NameClash
= rInfo
.NameClash
;
2083 // Transfer child to target.
2084 xTarget
->transfer( aInfo
, xEnv
);
2086 catch ( container::NoSuchElementException
const & )
2089 catch ( lang::WrappedTargetException
const & )
2096 //////////////////////////////////////////////////////////////////////
2097 // 5) Destroy source ( when moving only ) .
2098 //////////////////////////////////////////////////////////////////////
2100 if ( rInfo
.MoveData
)
2102 xSource
->destroy( sal_True
, xEnv
);
2104 // Remove all persistent data of source and its children.
2105 if ( !xSource
->removeData() )
2109 beans::PropertyValue(
2110 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
2114 xSource
->m_xIdentifier
->
2115 getContentIdentifier()),
2116 beans::PropertyState_DIRECT_VALUE
));
2117 ucbhelper::cancelCommandExecution(
2118 ucb::IOErrorCode_CANT_WRITE
,
2119 uno::Sequence
< uno::Any
>(&aProps
, 1),
2121 rtl::OUString::createFromAscii(
2122 "Cannot remove persistent data of source object!" ),
2127 // Remove own and all children's Additional Core Properties.
2128 xSource
->removeAdditionalPropertySet( sal_True
);
2132 //=========================================================================
2133 sal_Bool
Content::exchangeIdentity(
2134 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2139 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
2141 uno::Reference
< ucb::XContent
> xThis
= this;
2143 // Already persistent?
2144 if ( m_eState
!= PERSISTENT
)
2146 OSL_ENSURE( sal_False
,
2147 "Content::exchangeIdentity - Not persistent!" );
2151 // Exchange own identitity.
2153 // Fail, if a content with given id already exists.
2154 PackageUri
aNewUri( xNewId
->getContentIdentifier() );
2155 if ( !hasData( aNewUri
) )
2157 rtl::OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
2160 if ( exchange( xNewId
) )
2165 // Process instanciated children...
2167 ContentRefList aChildren
;
2168 queryChildren( aChildren
);
2170 ContentRefList::const_iterator it
= aChildren
.begin();
2171 ContentRefList::const_iterator end
= aChildren
.end();
2175 ContentRef xChild
= (*it
);
2177 // Create new content identifier for the child...
2178 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
2179 = xChild
->getIdentifier();
2180 rtl::OUString aOldChildURL
2181 = xOldChildId
->getContentIdentifier();
2182 rtl::OUString aNewChildURL
2183 = aOldChildURL
.replaceAt(
2185 aOldURL
.getLength(),
2186 xNewId
->getContentIdentifier() );
2187 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
2188 = new ::ucbhelper::ContentIdentifier(
2189 m_xSMgr
, aNewChildURL
);
2191 if ( !xChild
->exchangeIdentity( xNewChildId
) )
2201 OSL_ENSURE( sal_False
,
2202 "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2206 //=========================================================================
2207 void Content::queryChildren( ContentRefList
& rChildren
)
2209 // Obtain a list with a snapshot of all currently instanciated contents
2210 // from provider and extract the contents which are direct children
2213 ::ucbhelper::ContentRefList aAllContents
;
2214 m_xProvider
->queryExistingContents( aAllContents
);
2216 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
2218 OSL_ENSURE( aURL
.lastIndexOf( '/' ) != ( aURL
.getLength() - 1 ),
2219 "Content::queryChildren - Invalid URL!" );
2221 aURL
+= rtl::OUString::createFromAscii( "/" );
2223 sal_Int32 nLen
= aURL
.getLength();
2225 ::ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
2226 ::ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
2230 ::ucbhelper::ContentImplHelperRef xChild
= (*it
);
2231 rtl::OUString aChildURL
2232 = xChild
->getIdentifier()->getContentIdentifier();
2234 // Is aURL a prefix of aChildURL?
2235 if ( ( aChildURL
.getLength() > nLen
) &&
2236 ( aChildURL
.compareTo( aURL
, nLen
) == 0 ) )
2238 if ( aChildURL
.indexOf( '/', nLen
) == -1 )
2240 // No further slashes. It's a child!
2241 rChildren
.push_back(
2243 static_cast< Content
* >( xChild
.get() ) ) );
2250 //=========================================================================
2251 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage(
2252 const PackageUri
& rURI
)
2254 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2256 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2257 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2259 if ( !m_xPackage
.is() )
2260 m_xPackage
= m_pProvider
->createPackage( m_aUri
.getPackage(), m_aUri
.getParam() );
2265 return m_pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2268 //=========================================================================
2269 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage()
2271 return getPackage( m_aUri
);
2274 //=========================================================================
2276 sal_Bool
Content::hasData(
2277 ContentProvider
* pProvider
,
2278 const PackageUri
& rURI
,
2279 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2281 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2282 if ( !rxPackage
.is() )
2285 return rxPackage
->hasByHierarchicalName( rURI
.getPath() );
2288 //=========================================================================
2289 sal_Bool
Content::hasData( const PackageUri
& rURI
)
2291 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2293 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2294 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2296 xPackage
= getPackage();
2297 if ( !xPackage
.is() )
2300 return xPackage
->hasByHierarchicalName( rURI
.getPath() );
2303 return hasData( m_pProvider
, rURI
, xPackage
);
2306 //=========================================================================
2308 sal_Bool
Content::loadData(
2309 ContentProvider
* pProvider
,
2310 const PackageUri
& rURI
,
2311 ContentProperties
& rProps
,
2312 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2314 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2315 if ( !rxPackage
.is() )
2318 if ( rURI
.isRootFolder() )
2320 // Properties available only from package
2321 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2322 rxPackage
, uno::UNO_QUERY
);
2324 OSL_ENSURE( xPackagePropSet
.is(),
2325 "Content::loadData - "
2326 "Got no XPropertySet interface from package!" );
2328 if ( xPackagePropSet
.is() )
2330 // HasEncryptedEntries ( only avalibale at root folder )
2333 uno::Any aHasEncryptedEntries
2334 = xPackagePropSet
->getPropertyValue(
2335 rtl::OUString::createFromAscii(
2336 "HasEncryptedEntries" ) );
2337 if ( !( aHasEncryptedEntries
>>= rProps
.bHasEncryptedEntries
) )
2339 OSL_ENSURE( sal_False
,
2340 "Content::loadData - "
2341 "Got no HasEncryptedEntries value!" );
2345 catch ( beans::UnknownPropertyException
const & )
2347 OSL_ENSURE( sal_False
,
2348 "Content::loadData - "
2349 "Got no HasEncryptedEntries value!" );
2352 catch ( lang::WrappedTargetException
const & )
2354 OSL_ENSURE( sal_False
,
2355 "Content::loadData - "
2356 "Got no HasEncryptedEntries value!" );
2362 if ( !rxPackage
->hasByHierarchicalName( rURI
.getPath() ) )
2367 uno::Any aEntry
= rxPackage
->getByHierarchicalName( rURI
.getPath() );
2368 if ( aEntry
.hasValue() )
2370 uno::Reference
< beans::XPropertySet
> xPropSet
;
2371 aEntry
>>= xPropSet
;
2373 if ( !xPropSet
.is() )
2375 OSL_ENSURE( sal_False
,
2376 "Content::loadData - Got no XPropertySet interface!" );
2381 rProps
.aTitle
= rURI
.getName();
2387 = xPropSet
->getPropertyValue(
2388 rtl::OUString::createFromAscii( "MediaType" ) );
2389 if ( !( aMediaType
>>= rProps
.aMediaType
) )
2391 OSL_ENSURE( sal_False
,
2392 "Content::loadData - Got no MediaType value!" );
2396 catch ( beans::UnknownPropertyException
const & )
2398 OSL_ENSURE( sal_False
,
2399 "Content::loadData - Got no MediaType value!" );
2402 catch ( lang::WrappedTargetException
const & )
2404 OSL_ENSURE( sal_False
,
2405 "Content::loadData - Got no MediaType value!" );
2409 uno::Reference
< container::XEnumerationAccess
> xEnumAccess
;
2410 aEntry
>>= xEnumAccess
;
2412 // ContentType / IsFolder / IsDocument
2413 if ( xEnumAccess
.is() )
2416 rProps
.aContentType
= GetContentType( rURI
.getScheme(), sal_True
);
2417 rProps
.bIsDocument
= sal_False
;
2418 rProps
.bIsFolder
= sal_True
;
2423 rProps
.aContentType
= GetContentType( rURI
.getScheme(), sal_False
);
2424 rProps
.bIsDocument
= sal_True
;
2425 rProps
.bIsFolder
= sal_False
;
2428 if ( rProps
.bIsDocument
)
2430 // Size ( only available for streams )
2434 = xPropSet
->getPropertyValue(
2435 rtl::OUString::createFromAscii( "Size" ) );
2436 if ( !( aSize
>>= rProps
.nSize
) )
2438 OSL_ENSURE( sal_False
,
2439 "Content::loadData - Got no Size value!" );
2443 catch ( beans::UnknownPropertyException
const & )
2445 OSL_ENSURE( sal_False
,
2446 "Content::loadData - Got no Size value!" );
2449 catch ( lang::WrappedTargetException
const & )
2451 OSL_ENSURE( sal_False
,
2452 "Content::loadData - Got no Size value!" );
2456 // Compressed ( only available for streams )
2459 uno::Any aCompressed
2460 = xPropSet
->getPropertyValue(
2461 rtl::OUString::createFromAscii( "Compressed" ) );
2462 if ( !( aCompressed
>>= rProps
.bCompressed
) )
2464 OSL_ENSURE( sal_False
,
2465 "Content::loadData - Got no Compressed value!" );
2469 catch ( beans::UnknownPropertyException
const & )
2471 OSL_ENSURE( sal_False
,
2472 "Content::loadData - Got no Compressed value!" );
2475 catch ( lang::WrappedTargetException
const & )
2477 OSL_ENSURE( sal_False
,
2478 "Content::loadData - Got no Compressed value!" );
2482 // Encrypted ( only available for streams )
2486 = xPropSet
->getPropertyValue(
2487 rtl::OUString::createFromAscii( "Encrypted" ) );
2488 if ( !( aEncrypted
>>= rProps
.bEncrypted
) )
2490 OSL_ENSURE( sal_False
,
2491 "Content::loadData - Got no Encrypted value!" );
2495 catch ( beans::UnknownPropertyException
const & )
2497 OSL_ENSURE( sal_False
,
2498 "Content::loadData - Got no Encrypted value!" );
2501 catch ( lang::WrappedTargetException
const & )
2503 OSL_ENSURE( sal_False
,
2504 "Content::loadData - Got no Encrypted value!" );
2511 catch ( container::NoSuchElementException
const & )
2513 // getByHierarchicalName
2519 //=========================================================================
2520 sal_Bool
Content::renameData(
2521 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
2522 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2524 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2526 PackageUri
aURI( xOldId
->getContentIdentifier() );
2527 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage(
2532 if ( !xNA
->hasByHierarchicalName( aURI
.getPath() ) )
2537 uno::Any aEntry
= xNA
->getByHierarchicalName( aURI
.getPath() );
2538 uno::Reference
< container::XNamed
> xNamed
;
2543 OSL_ENSURE( sal_False
,
2544 "Content::renameData - Got no XNamed interface!" );
2548 PackageUri
aNewURI( xNewId
->getContentIdentifier() );
2550 // No success indicator!? No return value / exceptions specified.
2551 xNamed
->setName( aNewURI
.getName() );
2555 catch ( container::NoSuchElementException
const & )
2557 // getByHierarchicalName
2563 //=========================================================================
2564 sal_Bool
Content::storeData( const uno::Reference
< io::XInputStream
>& xStream
)
2566 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2568 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2572 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2573 xNA
, uno::UNO_QUERY
);
2574 OSL_ENSURE( xPackagePropSet
.is(),
2575 "Content::storeData - "
2576 "Got no XPropertySet interface from package!" );
2578 if ( !xPackagePropSet
.is() )
2581 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2583 if ( m_aUri
.isRootFolder() )
2585 // Property available only from package and from streams (see below)
2588 xPackagePropSet
->setPropertyValue(
2589 rtl::OUString::createFromAscii( "EncryptionKey" ),
2590 uno::makeAny( m_aProps
.aEncryptionKey
) );
2591 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2593 catch ( beans::UnknownPropertyException
const & )
2597 catch ( beans::PropertyVetoException
const & )
2601 catch ( lang::IllegalArgumentException
const & )
2605 catch ( lang::WrappedTargetException
const & )
2612 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2619 // Create new resource...
2620 uno::Reference
< lang::XSingleServiceFactory
> xFac(
2621 xNA
, uno::UNO_QUERY
);
2624 OSL_ENSURE( sal_False
,
2625 "Content::storeData - "
2626 "Got no XSingleServiceFactory interface!" );
2630 uno::Sequence
< uno::Any
> aArgs( 1 );
2631 aArgs
[ 0 ] <<= isFolder();
2633 uno::Reference
< uno::XInterface
> xNew
2634 = xFac
->createInstanceWithArguments( aArgs
);
2638 OSL_ENSURE( sal_False
,
2639 "Content::storeData - createInstance failed!" );
2643 PackageUri
aParentUri( getParentURL() );
2645 = xNA
->getByHierarchicalName( aParentUri
.getPath() );
2646 uno::Reference
< container::XNameContainer
> xParentContainer
;
2647 aEntry
>>= xParentContainer
;
2649 if ( !xParentContainer
.is() )
2651 OSL_ENSURE( sal_False
,
2652 "Content::storeData - "
2653 "Got no XNameContainer interface!" );
2657 xParentContainer
->insertByName( m_aProps
.aTitle
,
2658 uno::makeAny( xNew
) );
2660 catch ( uno::RuntimeException
const & )
2664 catch ( lang::IllegalArgumentException
const & )
2667 OSL_ENSURE( sal_False
,
2668 "Content::storeData - insertByName failed!" );
2671 catch ( container::ElementExistException
const & )
2674 OSL_ENSURE( sal_False
,
2675 "Content::storeData - insertByName failed!" );
2678 catch ( lang::WrappedTargetException
const & )
2681 OSL_ENSURE( sal_False
,
2682 "Content::storeData - insertByName failed!" );
2685 catch ( container::NoSuchElementException
const & )
2687 // getByHierarchicalName
2688 OSL_ENSURE( sal_False
,
2689 "Content::storeData - getByHierarchicalName failed!" );
2692 catch ( uno::Exception
const & )
2694 // createInstanceWithArguments
2695 OSL_ENSURE( sal_False
, "Content::storeData - Error!" );
2700 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2705 uno::Reference
< beans::XPropertySet
> xPropSet
;
2706 xNA
->getByHierarchicalName( m_aUri
.getPath() ) >>= xPropSet
;
2708 if ( !xPropSet
.is() )
2710 OSL_ENSURE( sal_False
,
2711 "Content::storeData - Got no XPropertySet interface!" );
2715 //////////////////////////////////////////////////////////////////
2716 // Store property values...
2717 //////////////////////////////////////////////////////////////////
2719 if ( m_nModifiedProps
& MEDIATYPE_MODIFIED
)
2721 xPropSet
->setPropertyValue(
2722 rtl::OUString::createFromAscii( "MediaType" ),
2723 uno::makeAny( m_aProps
.aMediaType
) );
2724 m_nModifiedProps
&= ~MEDIATYPE_MODIFIED
;
2727 if ( m_nModifiedProps
& COMPRESSED_MODIFIED
)
2730 xPropSet
->setPropertyValue(
2731 rtl::OUString::createFromAscii( "Compressed" ),
2732 uno::makeAny( m_aProps
.bCompressed
) );
2734 m_nModifiedProps
&= ~COMPRESSED_MODIFIED
;
2737 if ( m_nModifiedProps
& ENCRYPTED_MODIFIED
)
2740 xPropSet
->setPropertyValue(
2741 rtl::OUString::createFromAscii( "Encrypted" ),
2742 uno::makeAny( m_aProps
.bEncrypted
) );
2744 m_nModifiedProps
&= ~ENCRYPTED_MODIFIED
;
2747 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2750 xPropSet
->setPropertyValue(
2751 rtl::OUString::createFromAscii( "EncryptionKey" ),
2752 uno::makeAny( m_aProps
.aEncryptionKey
) );
2754 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2757 //////////////////////////////////////////////////////////////////
2758 // Store data stream...
2759 //////////////////////////////////////////////////////////////////
2761 if ( xStream
.is() && !isFolder() )
2763 uno::Reference
< io::XActiveDataSink
> xSink(
2764 xPropSet
, uno::UNO_QUERY
);
2768 OSL_ENSURE( sal_False
,
2769 "Content::storeData - "
2770 "Got no XActiveDataSink interface!" );
2774 xSink
->setInputStream( xStream
);
2779 catch ( container::NoSuchElementException
const & )
2781 // getByHierarchicalName
2783 catch ( beans::UnknownPropertyException
const & )
2787 catch ( beans::PropertyVetoException
const & )
2791 catch ( lang::IllegalArgumentException
const & )
2795 catch ( lang::WrappedTargetException
const & )
2800 OSL_ENSURE( sal_False
, "Content::storeData - Error!" );
2804 //=========================================================================
2805 sal_Bool
Content::removeData()
2807 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2809 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2813 PackageUri
aParentUri( getParentURL() );
2814 if ( !xNA
->hasByHierarchicalName( aParentUri
.getPath() ) )
2819 uno::Any aEntry
= xNA
->getByHierarchicalName( aParentUri
.getPath() );
2820 uno::Reference
< container::XNameContainer
> xContainer
;
2821 aEntry
>>= xContainer
;
2823 if ( !xContainer
.is() )
2825 OSL_ENSURE( sal_False
,
2826 "Content::removeData - "
2827 "Got no XNameContainer interface!" );
2831 xContainer
->removeByName( m_aUri
.getName() );
2834 catch ( container::NoSuchElementException
const & )
2836 // getByHierarchicalName, removeByName
2838 catch ( lang::WrappedTargetException
const & )
2843 OSL_ENSURE( sal_False
, "Content::removeData - Error!" );
2847 //=========================================================================
2848 sal_Bool
Content::flushData()
2850 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2852 // Note: XChangesBatch is only implemented by the package itself, not
2853 // by the single entries. Maybe this has to change...
2855 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2859 uno::Reference
< util::XChangesBatch
> xBatch( xNA
, uno::UNO_QUERY
);
2862 OSL_ENSURE( sal_False
,
2863 "Content::flushData - Got no XChangesBatch interface!" );
2869 xBatch
->commitChanges();
2872 catch ( lang::WrappedTargetException
const & )
2876 OSL_ENSURE( sal_False
, "Content::flushData - Error!" );
2880 //=========================================================================
2881 uno::Reference
< io::XInputStream
> Content::getInputStream()
2883 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2885 uno::Reference
< io::XInputStream
> xStream
;
2886 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2890 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2895 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2896 uno::Reference
< io::XActiveDataSink
> xSink
;
2901 OSL_ENSURE( sal_False
,
2902 "Content::getInputStream - "
2903 "Got no XActiveDataSink interface!" );
2907 xStream
= xSink
->getInputStream();
2909 OSL_ENSURE( xStream
.is(),
2910 "Content::getInputStream - Got no stream!" );
2912 catch ( container::NoSuchElementException
const & )
2914 // getByHierarchicalName
2920 //=========================================================================
2921 uno::Reference
< container::XEnumeration
> Content::getIterator()
2923 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2925 uno::Reference
< container::XEnumeration
> xIter
;
2926 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2930 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2935 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2936 uno::Reference
< container::XEnumerationAccess
> xIterFac
;
2937 aEntry
>>= xIterFac
;
2939 if ( !xIterFac
.is() )
2941 OSL_ENSURE( sal_False
,
2942 "Content::getIterator - "
2943 "Got no XEnumerationAccess interface!" );
2947 xIter
= xIterFac
->createEnumeration();
2949 OSL_ENSURE( xIter
.is(),
2950 "Content::getIterator - Got no iterator!" );
2952 catch ( container::NoSuchElementException
const & )
2954 // getByHierarchicalName