1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 /**************************************************************************
32 **************************************************************************
33 *************************************************************************/
34 #include <osl/diagnose.h>
36 #include "osl/doublecheckedlocking.h"
37 #include <rtl/ustring.h>
38 #include <rtl/ustring.hxx>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/beans/PropertyState.hpp>
41 #include <com/sun/star/beans/PropertyValue.hpp>
42 #include <com/sun/star/beans/XPropertyAccess.hpp>
43 #include <com/sun/star/container/XEnumerationAccess.hpp>
44 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 #include <com/sun/star/container/XNamed.hpp>
47 #include <com/sun/star/io/XActiveDataSink.hpp>
48 #include <com/sun/star/io/XInputStream.hpp>
49 #include <com/sun/star/io/XOutputStream.hpp>
50 #include <com/sun/star/lang/IllegalAccessException.hpp>
51 #include <com/sun/star/sdbc/XRow.hpp>
52 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
53 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
54 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
55 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
56 #include <com/sun/star/ucb/NameClash.hpp>
57 #include <com/sun/star/ucb/NameClashException.hpp>
58 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
59 #include <com/sun/star/ucb/OpenMode.hpp>
60 #include <com/sun/star/ucb/TransferInfo.hpp>
61 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
62 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
63 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
64 #include <com/sun/star/ucb/XCommandInfo.hpp>
65 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
66 #include <com/sun/star/util/XChangesBatch.hpp>
67 #include <com/sun/star/uno/Any.hxx>
68 #include <com/sun/star/uno/Sequence.hxx>
69 #include <ucbhelper/contentidentifier.hxx>
70 #include <ucbhelper/propertyvalueset.hxx>
71 #include <ucbhelper/cancelcommandexecution.hxx>
72 #include "pkgcontent.hxx"
73 #include "pkgprovider.hxx"
74 #include "pkgresultset.hxx"
76 #include "../inc/urihelper.hxx"
78 using namespace com::sun::star
;
79 using namespace package_ucp
;
81 #define NONE_MODIFIED sal_uInt32( 0x00 )
82 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
83 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
84 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
85 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
87 //=========================================================================
88 //=========================================================================
90 // ContentProperties Implementation.
92 //=========================================================================
93 //=========================================================================
95 ContentProperties::ContentProperties( const rtl::OUString
& rContentType
)
96 : aContentType( rContentType
),
98 bCompressed( sal_True
),
99 bEncrypted( sal_False
),
100 bHasEncryptedEntries( sal_False
)
102 bIsFolder
= rContentType
== PACKAGE_FOLDER_CONTENT_TYPE
|| rContentType
== PACKAGE_ZIP_FOLDER_CONTENT_TYPE
;
103 bIsDocument
= !bIsFolder
;
105 OSL_ENSURE( bIsFolder
|| rContentType
== PACKAGE_STREAM_CONTENT_TYPE
|| rContentType
== PACKAGE_ZIP_STREAM_CONTENT_TYPE
,
106 "ContentProperties::ContentProperties - Unknown type!" );
109 //=========================================================================
111 uno::Sequence
< ucb::ContentInfo
>
112 ContentProperties::getCreatableContentsInfo( PackageUri
const & rUri
) const
116 uno::Sequence
< beans::Property
> aProps( 1 );
117 aProps
.getArray()[ 0 ] = beans::Property(
118 rtl::OUString("Title"),
120 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
121 beans::PropertyAttribute::BOUND
);
123 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
126 aSeq
.getArray()[ 0 ].Type
127 = Content::getContentType( rUri
.getScheme(), sal_True
);
128 aSeq
.getArray()[ 0 ].Attributes
129 = ucb::ContentInfoAttribute::KIND_FOLDER
;
130 aSeq
.getArray()[ 0 ].Properties
= aProps
;
133 aSeq
.getArray()[ 1 ].Type
134 = Content::getContentType( rUri
.getScheme(), sal_False
);
135 aSeq
.getArray()[ 1 ].Attributes
136 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
137 | ucb::ContentInfoAttribute::KIND_DOCUMENT
;
138 aSeq
.getArray()[ 1 ].Properties
= aProps
;
144 return uno::Sequence
< ucb::ContentInfo
>( 0 );
148 //=========================================================================
149 //=========================================================================
151 // Content Implementation.
153 //=========================================================================
154 //=========================================================================
156 // static ( "virtual" ctor )
157 Content
* Content::create(
158 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
159 ContentProvider
* pProvider
,
160 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
162 rtl::OUString aURL
= Identifier
->getContentIdentifier();
163 PackageUri
aURI( aURL
);
164 ContentProperties aProps
;
165 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
167 if ( loadData( pProvider
, aURI
, aProps
, xPackage
) )
171 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
172 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
174 // Client explicitly requested a folder!
175 if ( !aProps
.bIsFolder
)
179 uno::Reference
< ucb::XContentIdentifier
> xId
180 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
181 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, aProps
);
185 // resource doesn't exist
187 sal_Bool bFolder
= sal_False
;
189 // Guess type according to URI.
190 sal_Int32 nLastSlash
= aURL
.lastIndexOf( '/' );
191 if ( ( nLastSlash
+ 1 ) == aURL
.getLength() )
194 uno::Reference
< ucb::XContentIdentifier
> xId
195 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
197 ucb::ContentInfo aInfo
;
198 if ( bFolder
|| aURI
.isRootFolder() )
199 aInfo
.Type
= getContentType( aURI
.getScheme(), sal_True
);
201 aInfo
.Type
= getContentType( aURI
.getScheme(), sal_False
);
203 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, aInfo
);
207 //=========================================================================
208 // static ( "virtual" ctor )
209 Content
* Content::create(
210 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
211 ContentProvider
* pProvider
,
212 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
213 const ucb::ContentInfo
& Info
)
215 if ( Info
.Type
.isEmpty() )
218 PackageUri
aURI( Identifier
->getContentIdentifier() );
220 if ( !Info
.Type
.equalsIgnoreAsciiCase(
221 getContentType( aURI
.getScheme(), sal_True
) ) &&
222 !Info
.Type
.equalsIgnoreAsciiCase(
223 getContentType( aURI
.getScheme(), sal_False
) ) )
226 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
228 xPackage
= pProvider
->createPackage( aURI
.getPackage(), aURI
.getParam() );
230 uno::Reference
< ucb::XContentIdentifier
> xId
231 = new ::ucbhelper::ContentIdentifier( rxSMgr
, aURI
.getUri() );
232 return new Content( rxSMgr
, pProvider
, xId
, xPackage
, aURI
, Info
);
235 //=========================================================================
237 ::rtl::OUString
Content::getContentType(
238 const ::rtl::OUString
& aScheme
, sal_Bool bFolder
)
240 return ( rtl::OUString("application/")
243 ? rtl::OUString("-folder")
244 : rtl::OUString("-stream") ) );
247 //=========================================================================
249 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
250 ContentProvider
* pProvider
,
251 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
252 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
253 const PackageUri
& rUri
,
254 const ContentProperties
& rProps
)
255 : ContentImplHelper( rxSMgr
, pProvider
, Identifier
),
258 m_eState( PERSISTENT
),
259 m_xPackage( Package
),
260 m_pProvider( pProvider
),
261 m_nModifiedProps( NONE_MODIFIED
)
265 //=========================================================================
267 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
268 ContentProvider
* pProvider
,
269 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
270 const uno::Reference
< container::XHierarchicalNameAccess
> & Package
,
271 const PackageUri
& rUri
,
272 const ucb::ContentInfo
& Info
)
273 : ContentImplHelper( rxSMgr
, pProvider
, Identifier
),
275 m_aProps( Info
.Type
),
276 m_eState( TRANSIENT
),
277 m_xPackage( Package
),
278 m_pProvider( pProvider
),
279 m_nModifiedProps( NONE_MODIFIED
)
283 //=========================================================================
289 //=========================================================================
291 // XInterface methods.
293 //=========================================================================
296 void SAL_CALL
Content::acquire()
299 ContentImplHelper::acquire();
302 //=========================================================================
304 void SAL_CALL
Content::release()
307 ContentImplHelper::release();
310 //=========================================================================
312 uno::Any SAL_CALL
Content::queryInterface( const uno::Type
& rType
)
313 throw ( uno::RuntimeException
)
318 aRet
= cppu::queryInterface(
319 rType
, static_cast< ucb::XContentCreator
* >( this ) );
321 return aRet
.hasValue() ? aRet
: ContentImplHelper::queryInterface( rType
);
324 //=========================================================================
326 // XTypeProvider methods.
328 //=========================================================================
330 XTYPEPROVIDER_COMMON_IMPL( Content
);
332 //=========================================================================
334 uno::Sequence
< uno::Type
> SAL_CALL
Content::getTypes()
335 throw( uno::RuntimeException
)
337 cppu::OTypeCollection
* pCollection
= 0;
341 static cppu::OTypeCollection
* pFolderTypes
= 0;
343 pCollection
= pFolderTypes
;
346 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
348 pCollection
= pFolderTypes
;
351 static cppu::OTypeCollection
aCollection(
352 CPPU_TYPE_REF( lang::XTypeProvider
),
353 CPPU_TYPE_REF( lang::XServiceInfo
),
354 CPPU_TYPE_REF( lang::XComponent
),
355 CPPU_TYPE_REF( ucb::XContent
),
356 CPPU_TYPE_REF( ucb::XCommandProcessor
),
357 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
358 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
359 CPPU_TYPE_REF( beans::XPropertyContainer
),
360 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
361 CPPU_TYPE_REF( container::XChild
),
362 CPPU_TYPE_REF( ucb::XContentCreator
) ); // !!
363 pCollection
= &aCollection
;
364 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
365 pFolderTypes
= pCollection
;
369 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
374 static cppu::OTypeCollection
* pDocumentTypes
= 0;
376 pCollection
= pDocumentTypes
;
379 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
381 pCollection
= pDocumentTypes
;
384 static cppu::OTypeCollection
aCollection(
385 CPPU_TYPE_REF( lang::XTypeProvider
),
386 CPPU_TYPE_REF( lang::XServiceInfo
),
387 CPPU_TYPE_REF( lang::XComponent
),
388 CPPU_TYPE_REF( ucb::XContent
),
389 CPPU_TYPE_REF( ucb::XCommandProcessor
),
390 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
391 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
392 CPPU_TYPE_REF( beans::XPropertyContainer
),
393 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
394 CPPU_TYPE_REF( container::XChild
) );
395 pCollection
= &aCollection
;
396 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
397 pDocumentTypes
= pCollection
;
401 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
405 return (*pCollection
).getTypes();
408 //=========================================================================
410 // XServiceInfo methods.
412 //=========================================================================
415 rtl::OUString SAL_CALL
Content::getImplementationName()
416 throw( uno::RuntimeException
)
418 return rtl::OUString( "com.sun.star.comp.ucb.PackageContent" );
421 //=========================================================================
423 uno::Sequence
< rtl::OUString
> SAL_CALL
Content::getSupportedServiceNames()
424 throw( uno::RuntimeException
)
426 uno::Sequence
< rtl::OUString
> aSNS( 1 );
428 aSNS
.getArray()[ 0 ] = rtl::OUString( PACKAGE_FOLDER_CONTENT_SERVICE_NAME
);
430 aSNS
.getArray()[ 0 ] = rtl::OUString( PACKAGE_STREAM_CONTENT_SERVICE_NAME
);
435 //=========================================================================
439 //=========================================================================
442 rtl::OUString SAL_CALL
Content::getContentType()
443 throw( uno::RuntimeException
)
445 return m_aProps
.aContentType
;
448 //=========================================================================
450 // XCommandProcessor methods.
452 //=========================================================================
455 uno::Any SAL_CALL
Content::execute(
456 const ucb::Command
& aCommand
,
457 sal_Int32
/*CommandId*/,
458 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
459 throw( uno::Exception
,
460 ucb::CommandAbortedException
,
461 uno::RuntimeException
)
465 if ( aCommand
.Name
== "getPropertyValues" )
467 //////////////////////////////////////////////////////////////////
469 //////////////////////////////////////////////////////////////////
471 uno::Sequence
< beans::Property
> Properties
;
472 if ( !( aCommand
.Argument
>>= Properties
) )
474 ucbhelper::cancelCommandExecution(
475 uno::makeAny( lang::IllegalArgumentException(
476 rtl::OUString( "Wrong argument type!" ),
477 static_cast< cppu::OWeakObject
* >( this ),
483 aRet
<<= getPropertyValues( Properties
);
485 else if ( aCommand
.Name
== "setPropertyValues" )
487 //////////////////////////////////////////////////////////////////
489 //////////////////////////////////////////////////////////////////
491 uno::Sequence
< beans::PropertyValue
> aProperties
;
492 if ( !( aCommand
.Argument
>>= aProperties
) )
494 ucbhelper::cancelCommandExecution(
495 uno::makeAny( lang::IllegalArgumentException(
496 rtl::OUString( "Wrong argument type!" ),
497 static_cast< cppu::OWeakObject
* >( this ),
503 if ( !aProperties
.getLength() )
505 ucbhelper::cancelCommandExecution(
506 uno::makeAny( lang::IllegalArgumentException(
507 rtl::OUString( "No properties!" ),
508 static_cast< cppu::OWeakObject
* >( this ),
514 aRet
<<= setPropertyValues( aProperties
, Environment
);
516 else if ( aCommand
.Name
== "getPropertySetInfo" )
518 //////////////////////////////////////////////////////////////////
519 // getPropertySetInfo
520 //////////////////////////////////////////////////////////////////
522 // Note: Implemented by base class.
523 aRet
<<= getPropertySetInfo( Environment
);
525 else if ( aCommand
.Name
== "getCommandInfo" )
527 //////////////////////////////////////////////////////////////////
529 //////////////////////////////////////////////////////////////////
531 // Note: Implemented by base class.
532 aRet
<<= getCommandInfo( Environment
);
534 else if ( aCommand
.Name
== "open" )
536 //////////////////////////////////////////////////////////////////
538 //////////////////////////////////////////////////////////////////
540 ucb::OpenCommandArgument2 aOpenCommand
;
541 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
543 ucbhelper::cancelCommandExecution(
544 uno::makeAny( lang::IllegalArgumentException(
545 rtl::OUString( "Wrong argument type!" ),
546 static_cast< cppu::OWeakObject
* >( this ),
552 aRet
= open( aOpenCommand
, Environment
);
554 else if ( !m_aUri
.isRootFolder() && aCommand
.Name
== "insert" )
556 //////////////////////////////////////////////////////////////////
558 //////////////////////////////////////////////////////////////////
560 ucb::InsertCommandArgument aArg
;
561 if ( !( aCommand
.Argument
>>= aArg
) )
563 ucbhelper::cancelCommandExecution(
564 uno::makeAny( lang::IllegalArgumentException(
565 rtl::OUString( "Wrong argument type!" ),
566 static_cast< cppu::OWeakObject
* >( this ),
572 sal_Int32 nNameClash
= aArg
.ReplaceExisting
573 ? ucb::NameClash::OVERWRITE
574 : ucb::NameClash::ERROR
;
575 insert( aArg
.Data
, nNameClash
, Environment
);
577 else if ( !m_aUri
.isRootFolder() && aCommand
.Name
== "delete" )
579 //////////////////////////////////////////////////////////////////
581 //////////////////////////////////////////////////////////////////
583 sal_Bool bDeletePhysical
= sal_False
;
584 aCommand
.Argument
>>= bDeletePhysical
;
585 destroy( bDeletePhysical
, Environment
);
587 // Remove own and all children's persistent data.
592 beans::PropertyValue(
593 rtl::OUString( "Uri"),
595 uno::makeAny(m_xIdentifier
->
596 getContentIdentifier()),
597 beans::PropertyState_DIRECT_VALUE
));
598 ucbhelper::cancelCommandExecution(
599 ucb::IOErrorCode_CANT_WRITE
,
600 uno::Sequence
< uno::Any
>(&aProps
, 1),
602 rtl::OUString( "Cannot remove persistent data!" ),
607 // Remove own and all children's Additional Core Properties.
608 removeAdditionalPropertySet( sal_True
);
610 else if ( aCommand
.Name
== "transfer" )
612 //////////////////////////////////////////////////////////////////
614 // ( Not available at stream objects )
615 //////////////////////////////////////////////////////////////////
617 ucb::TransferInfo aInfo
;
618 if ( !( aCommand
.Argument
>>= aInfo
) )
620 ucbhelper::cancelCommandExecution(
621 uno::makeAny( lang::IllegalArgumentException(
622 rtl::OUString( "Wrong argument type!" ),
623 static_cast< cppu::OWeakObject
* >( this ),
629 transfer( aInfo
, Environment
);
631 else if ( aCommand
.Name
== "createNewContent" && isFolder() )
633 //////////////////////////////////////////////////////////////////
635 // ( Not available at stream objects )
636 //////////////////////////////////////////////////////////////////
638 ucb::ContentInfo aInfo
;
639 if ( !( aCommand
.Argument
>>= aInfo
) )
641 OSL_FAIL( "Wrong argument type!" );
642 ucbhelper::cancelCommandExecution(
643 uno::makeAny( lang::IllegalArgumentException(
644 rtl::OUString( "Wrong argument type!" ),
645 static_cast< cppu::OWeakObject
* >( this ),
651 aRet
<<= createNewContent( aInfo
);
653 else if ( aCommand
.Name
== "flush" )
655 //////////////////////////////////////////////////////////////////
657 // ( Not available at stream objects )
658 //////////////////////////////////////////////////////////////////
664 beans::PropertyValue(
665 rtl::OUString( "Uri"),
667 uno::makeAny(m_xIdentifier
->
668 getContentIdentifier()),
669 beans::PropertyState_DIRECT_VALUE
));
670 ucbhelper::cancelCommandExecution(
671 ucb::IOErrorCode_CANT_WRITE
,
672 uno::Sequence
< uno::Any
>(&aProps
, 1),
674 rtl::OUString( "Cannot write file to disk!" ),
681 //////////////////////////////////////////////////////////////////
682 // Unsupported command
683 //////////////////////////////////////////////////////////////////
685 ucbhelper::cancelCommandExecution(
686 uno::makeAny( ucb::UnsupportedCommandException(
688 static_cast< cppu::OWeakObject
* >( this ) ) ),
696 //=========================================================================
698 void SAL_CALL
Content::abort( sal_Int32
/*CommandId*/ )
699 throw( uno::RuntimeException
)
701 // @@@ Implement logic to abort running commands, if this makes
702 // sense for your content.
705 //=========================================================================
707 // XContentCreator methods.
709 //=========================================================================
712 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
713 Content::queryCreatableContentsInfo()
714 throw( uno::RuntimeException
)
716 return m_aProps
.getCreatableContentsInfo( m_aUri
);
719 //=========================================================================
721 uno::Reference
< ucb::XContent
> SAL_CALL
722 Content::createNewContent( const ucb::ContentInfo
& Info
)
723 throw( uno::RuntimeException
)
727 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
729 if ( Info
.Type
.isEmpty() )
730 return uno::Reference
< ucb::XContent
>();
732 if ( !Info
.Type
.equalsIgnoreAsciiCase(
733 getContentType( m_aUri
.getScheme(), sal_True
) ) &&
734 !Info
.Type
.equalsIgnoreAsciiCase(
735 getContentType( m_aUri
.getScheme(), sal_False
) ) )
736 return uno::Reference
< ucb::XContent
>();
738 rtl::OUString aURL
= m_aUri
.getUri();
739 aURL
+= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
741 if ( Info
.Type
.equalsIgnoreAsciiCase(
742 getContentType( m_aUri
.getScheme(), sal_True
) ) )
743 aURL
+= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("New_Folder"));
745 aURL
+= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("New_Stream"));
747 uno::Reference
< ucb::XContentIdentifier
> xId(
748 new ::ucbhelper::ContentIdentifier( m_xSMgr
, aURL
) );
750 return create( m_xSMgr
, m_pProvider
, xId
, Info
);
754 OSL_FAIL( "createNewContent called on non-folder object!" );
755 return uno::Reference
< ucb::XContent
>();
759 //=========================================================================
761 // Non-interface methods.
763 //=========================================================================
766 rtl::OUString
Content::getParentURL()
768 return m_aUri
.getParentUri();
771 //=========================================================================
773 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
774 const uno::Reference
< lang::XMultiServiceFactory
>& rSMgr
,
775 const uno::Sequence
< beans::Property
>& rProperties
,
776 ContentProvider
* pProvider
,
777 const rtl::OUString
& rContentId
)
779 ContentProperties aData
;
780 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
781 if ( loadData( pProvider
, PackageUri( rContentId
), aData
, xPackage
) )
783 return getPropertyValues( rSMgr
,
787 ::ucbhelper::ContentProviderImplHelper
>(
793 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
794 = new ::ucbhelper::PropertyValueSet( rSMgr
);
796 sal_Int32 nCount
= rProperties
.getLength();
799 const beans::Property
* pProps
= rProperties
.getConstArray();
800 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
801 xRow
->appendVoid( pProps
[ n
] );
804 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
808 //=========================================================================
810 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
811 const uno::Reference
< lang::XMultiServiceFactory
>& rSMgr
,
812 const uno::Sequence
< beans::Property
>& rProperties
,
813 const ContentProperties
& rData
,
814 const rtl::Reference
< ::ucbhelper::ContentProviderImplHelper
>&
816 const rtl::OUString
& rContentId
)
818 // Note: Empty sequence means "get values of all supported properties".
820 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
821 = new ::ucbhelper::PropertyValueSet( rSMgr
);
823 sal_Int32 nCount
= rProperties
.getLength();
826 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
827 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
829 const beans::Property
* pProps
= rProperties
.getConstArray();
830 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
832 const beans::Property
& rProp
= pProps
[ n
];
834 // Process Core properties.
836 if ( rProp
.Name
== "ContentType" )
838 xRow
->appendString ( rProp
, rData
.aContentType
);
840 else if ( rProp
.Name
== "Title" )
842 xRow
->appendString ( rProp
, rData
.aTitle
);
844 else if ( rProp
.Name
== "IsDocument" )
846 xRow
->appendBoolean( rProp
, rData
.bIsDocument
);
848 else if ( rProp
.Name
== "IsFolder" )
850 xRow
->appendBoolean( rProp
, rData
.bIsFolder
);
852 else if ( rProp
.Name
== "CreatableContentsInfo" )
856 rData
.getCreatableContentsInfo(
857 PackageUri( rContentId
) ) ) );
859 else if ( rProp
.Name
== "MediaType" )
861 xRow
->appendString ( rProp
, rData
.aMediaType
);
863 else if ( rProp
.Name
== "Size" )
865 // Property only available for streams.
866 if ( rData
.bIsDocument
)
867 xRow
->appendLong( rProp
, rData
.nSize
);
869 xRow
->appendVoid( rProp
);
871 else if ( rProp
.Name
== "Compressed" )
873 // Property only available for streams.
874 if ( rData
.bIsDocument
)
875 xRow
->appendBoolean( rProp
, rData
.bCompressed
);
877 xRow
->appendVoid( rProp
);
879 else if ( rProp
.Name
== "Encrypted" )
881 // Property only available for streams.
882 if ( rData
.bIsDocument
)
883 xRow
->appendBoolean( rProp
, rData
.bEncrypted
);
885 xRow
->appendVoid( rProp
);
887 else if ( rProp
.Name
== "HasEncryptedEntries" )
889 // Property only available for root folder.
890 PackageUri
aURI( rContentId
);
891 if ( aURI
.isRootFolder() )
892 xRow
->appendBoolean( rProp
, rData
.bHasEncryptedEntries
);
894 xRow
->appendVoid( rProp
);
898 // Not a Core Property! Maybe it's an Additional Core Property?!
900 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
903 = uno::Reference
< beans::XPropertySet
>(
904 rProvider
->getAdditionalPropertySet( rContentId
,
907 bTriedToGetAdditonalPropSet
= sal_True
;
910 if ( xAdditionalPropSet
.is() )
912 if ( !xRow
->appendPropertySetValue(
916 // Append empty entry.
917 xRow
->appendVoid( rProp
);
922 // Append empty entry.
923 xRow
->appendVoid( rProp
);
930 // Append all Core Properties.
933 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContentType")),
935 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
936 beans::PropertyAttribute::BOUND
937 | beans::PropertyAttribute::READONLY
),
938 rData
.aContentType
);
941 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
943 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
944 beans::PropertyAttribute::BOUND
),
948 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsDocument")),
950 getCppuBooleanType(),
951 beans::PropertyAttribute::BOUND
952 | beans::PropertyAttribute::READONLY
),
956 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsFolder")),
958 getCppuBooleanType(),
959 beans::PropertyAttribute::BOUND
960 | beans::PropertyAttribute::READONLY
),
964 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreatableContentsInfo")),
966 getCppuType( static_cast<
967 const uno::Sequence
< ucb::ContentInfo
> * >( 0 ) ),
968 beans::PropertyAttribute::BOUND
969 | beans::PropertyAttribute::READONLY
),
971 rData
.getCreatableContentsInfo( PackageUri( rContentId
) ) ) );
974 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")),
976 getCppuType( static_cast< const rtl::OUString
* >( 0 ) ),
977 beans::PropertyAttribute::BOUND
),
980 // Properties only available for streams.
981 if ( rData
.bIsDocument
)
985 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Size")),
987 getCppuType( static_cast< const sal_Int64
* >( 0 ) ),
988 beans::PropertyAttribute::BOUND
989 | beans::PropertyAttribute::READONLY
),
994 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")),
996 getCppuBooleanType(),
997 beans::PropertyAttribute::BOUND
),
1000 xRow
->appendBoolean(
1002 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Encrypted")),
1004 getCppuBooleanType(),
1005 beans::PropertyAttribute::BOUND
),
1009 // Properties only available for root folder.
1010 PackageUri
aURI( rContentId
);
1011 if ( aURI
.isRootFolder() )
1013 xRow
->appendBoolean(
1015 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasEncryptedEntries")),
1017 getCppuBooleanType(),
1018 beans::PropertyAttribute::BOUND
1019 | beans::PropertyAttribute::READONLY
),
1020 rData
.bHasEncryptedEntries
);
1023 // Append all Additional Core Properties.
1025 uno::Reference
< beans::XPropertySet
> xSet(
1026 rProvider
->getAdditionalPropertySet( rContentId
, sal_False
),
1028 xRow
->appendPropertySet( xSet
);
1031 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
1034 //=========================================================================
1035 uno::Reference
< sdbc::XRow
> Content::getPropertyValues(
1036 const uno::Sequence
< beans::Property
>& rProperties
)
1038 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1039 return getPropertyValues( m_xSMgr
,
1043 ::ucbhelper::ContentProviderImplHelper
>(
1044 m_xProvider
.get() ),
1045 m_xIdentifier
->getContentIdentifier() );
1048 //=========================================================================
1049 uno::Sequence
< uno::Any
> Content::setPropertyValues(
1050 const uno::Sequence
< beans::PropertyValue
>& rValues
,
1051 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1052 throw( uno::Exception
)
1054 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1056 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
1057 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
1058 sal_Int32 nChanged
= 0;
1060 beans::PropertyChangeEvent aEvent
;
1061 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
1062 aEvent
.Further
= sal_False
;
1063 // aEvent.PropertyName =
1064 aEvent
.PropertyHandle
= -1;
1065 // aEvent.OldValue =
1066 // aEvent.NewValue =
1068 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1069 sal_Int32 nCount
= rValues
.getLength();
1071 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1072 sal_Bool bTriedToGetAdditonalPropSet
= sal_False
;
1073 sal_Bool bExchange
= sal_False
;
1074 sal_Bool bStore
= sal_False
;
1075 rtl::OUString aNewTitle
;
1076 sal_Int32 nTitlePos
= -1;
1078 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1080 const beans::PropertyValue
& rValue
= pValues
[ n
];
1082 if ( rValue
.Name
== "ContentType" )
1084 // Read-only property!
1085 aRet
[ n
] <<= lang::IllegalAccessException(
1086 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1087 "Property is read-only!" )),
1088 static_cast< cppu::OWeakObject
* >( this ) );
1090 else if ( rValue
.Name
== "IsDocument" )
1092 // Read-only property!
1093 aRet
[ n
] <<= lang::IllegalAccessException(
1094 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1095 "Property is read-only!" )),
1096 static_cast< cppu::OWeakObject
* >( this ) );
1098 else if ( rValue
.Name
== "IsFolder" )
1100 // Read-only property!
1101 aRet
[ n
] <<= lang::IllegalAccessException(
1102 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1103 "Property is read-only!" )),
1104 static_cast< cppu::OWeakObject
* >( this ) );
1106 else if ( rValue
.Name
== "CreatableContentsInfo" )
1108 // Read-only property!
1109 aRet
[ n
] <<= lang::IllegalAccessException(
1110 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1111 "Property is read-only!" )),
1112 static_cast< cppu::OWeakObject
* >( this ) );
1114 else if ( rValue
.Name
== "Title" )
1116 if ( m_aUri
.isRootFolder() )
1118 // Read-only property!
1119 aRet
[ n
] <<= lang::IllegalAccessException(
1120 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1121 "Property is read-only!" )),
1122 static_cast< cppu::OWeakObject
* >( this ) );
1126 rtl::OUString aNewValue
;
1127 if ( rValue
.Value
>>= aNewValue
)
1130 if ( !aNewValue
.isEmpty() )
1132 if ( aNewValue
!= m_aProps
.aTitle
)
1134 // modified title -> modified URL -> exchange !
1135 if ( m_eState
== PERSISTENT
)
1136 bExchange
= sal_True
;
1138 // new value will be set later...
1139 aNewTitle
= aNewValue
;
1141 // remember position within sequence of values
1142 // (for error handling).
1149 lang::IllegalArgumentException(
1150 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1151 "Empty title not allowed!" )),
1152 static_cast< cppu::OWeakObject
* >( this ),
1159 beans::IllegalTypeException(
1160 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1161 "Property value has wrong type!" )),
1162 static_cast< cppu::OWeakObject
* >( this ) );
1166 else if ( rValue
.Name
== "MediaType" )
1168 rtl::OUString aNewValue
;
1169 if ( rValue
.Value
>>= aNewValue
)
1171 if ( aNewValue
!= m_aProps
.aMediaType
)
1173 aEvent
.PropertyName
= rValue
.Name
;
1174 aEvent
.OldValue
= uno::makeAny( m_aProps
.aMediaType
);
1175 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1177 m_aProps
.aMediaType
= aNewValue
;
1180 m_nModifiedProps
|= MEDIATYPE_MODIFIED
;
1185 aRet
[ n
] <<= beans::IllegalTypeException(
1186 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1187 "Property value has wrong type!" )),
1188 static_cast< cppu::OWeakObject
* >( this ) );
1191 else if ( rValue
.Name
== "Size" )
1193 // Read-only property!
1194 aRet
[ n
] <<= lang::IllegalAccessException(
1195 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1196 "Property is read-only!" )),
1197 static_cast< cppu::OWeakObject
* >( this ) );
1199 else if ( rValue
.Name
== "Compressed" )
1201 // Property only available for streams.
1202 if ( m_aProps
.bIsDocument
)
1205 if ( rValue
.Value
>>= bNewValue
)
1207 if ( bNewValue
!= m_aProps
.bCompressed
)
1209 aEvent
.PropertyName
= rValue
.Name
;
1210 aEvent
.OldValue
= uno::makeAny( m_aProps
.bCompressed
);
1211 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1213 m_aProps
.bCompressed
= bNewValue
;
1216 m_nModifiedProps
|= COMPRESSED_MODIFIED
;
1221 aRet
[ n
] <<= beans::IllegalTypeException(
1222 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1223 "Property value has wrong type!" )),
1224 static_cast< cppu::OWeakObject
* >( this ) );
1229 aRet
[ n
] <<= beans::UnknownPropertyException(
1230 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1231 "Compressed only supported by streams!" )),
1232 static_cast< cppu::OWeakObject
* >( this ) );
1235 else if ( rValue
.Name
== "Encrypted" )
1237 // Property only available for streams.
1238 if ( m_aProps
.bIsDocument
)
1241 if ( rValue
.Value
>>= bNewValue
)
1243 if ( bNewValue
!= m_aProps
.bEncrypted
)
1245 aEvent
.PropertyName
= rValue
.Name
;
1246 aEvent
.OldValue
= uno::makeAny( m_aProps
.bEncrypted
);
1247 aEvent
.NewValue
= uno::makeAny( bNewValue
);
1249 m_aProps
.bEncrypted
= bNewValue
;
1252 m_nModifiedProps
|= ENCRYPTED_MODIFIED
;
1257 aRet
[ n
] <<= beans::IllegalTypeException(
1258 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1259 "Property value has wrong type!" )),
1260 static_cast< cppu::OWeakObject
* >( this ) );
1265 aRet
[ n
] <<= beans::UnknownPropertyException(
1266 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1267 "Encrypted only supported by streams!" )),
1268 static_cast< cppu::OWeakObject
* >( this ) );
1271 else if ( rValue
.Name
== "HasEncryptedEntries" )
1273 // Read-only property!
1274 aRet
[ n
] <<= lang::IllegalAccessException(
1275 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1276 "Property is read-only!" )),
1277 static_cast< cppu::OWeakObject
* >( this ) );
1279 else if ( rValue
.Name
== "EncryptionKey" )
1281 // @@@ This is a temporary solution. In the future submitting
1282 // the key should be done using an interaction handler!
1284 // Write-Only property. Only supported by root folder and streams
1285 // (all non-root folders of a package have the same encryption key).
1286 if ( m_aUri
.isRootFolder() || m_aProps
.bIsDocument
)
1288 uno::Sequence
< sal_Int8
> aNewValue
;
1289 if ( rValue
.Value
>>= aNewValue
)
1291 if ( aNewValue
!= m_aProps
.aEncryptionKey
)
1293 aEvent
.PropertyName
= rValue
.Name
;
1294 aEvent
.OldValue
= uno::makeAny(
1295 m_aProps
.aEncryptionKey
);
1296 aEvent
.NewValue
= uno::makeAny( aNewValue
);
1298 m_aProps
.aEncryptionKey
= aNewValue
;
1301 m_nModifiedProps
|= ENCRYPTIONKEY_MODIFIED
;
1306 aRet
[ n
] <<= beans::IllegalTypeException(
1307 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1308 "Property value has wrong type!" )),
1309 static_cast< cppu::OWeakObject
* >( this ) );
1314 aRet
[ n
] <<= beans::UnknownPropertyException(
1315 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1316 "EncryptionKey not supported by non-root folder!" )),
1317 static_cast< cppu::OWeakObject
* >( this ) );
1322 // Not a Core Property! Maybe it's an Additional Core Property?!
1324 if ( !bTriedToGetAdditonalPropSet
&& !xAdditionalPropSet
.is() )
1326 xAdditionalPropSet
= getAdditionalPropertySet( sal_False
);
1327 bTriedToGetAdditonalPropSet
= sal_True
;
1330 if ( xAdditionalPropSet
.is() )
1335 = xAdditionalPropSet
->getPropertyValue( rValue
.Name
);
1336 if ( aOldValue
!= rValue
.Value
)
1338 xAdditionalPropSet
->setPropertyValue(
1339 rValue
.Name
, rValue
.Value
);
1341 aEvent
.PropertyName
= rValue
.Name
;
1342 aEvent
.OldValue
= aOldValue
;
1343 aEvent
.NewValue
= rValue
.Value
;
1345 aChanges
.getArray()[ nChanged
] = aEvent
;
1349 catch ( beans::UnknownPropertyException
const & e
)
1353 catch ( lang::WrappedTargetException
const & e
)
1357 catch ( beans::PropertyVetoException
const & e
)
1361 catch ( lang::IllegalArgumentException
const & e
)
1368 aRet
[ n
] <<= uno::Exception(
1369 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1370 "No property set for storing the value!" )),
1371 static_cast< cppu::OWeakObject
* >( this ) );
1378 uno::Reference
< ucb::XContentIdentifier
> xOldId
= m_xIdentifier
;
1380 // Assemble new content identifier...
1381 rtl::OUString aNewURL
= m_aUri
.getParentUri();
1382 aNewURL
+= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
1383 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( aNewTitle
);
1384 uno::Reference
< ucb::XContentIdentifier
> xNewId
1385 = new ::ucbhelper::ContentIdentifier( m_xSMgr
, aNewURL
);
1388 if ( exchangeIdentity( xNewId
) )
1390 // Adapt persistent data.
1391 renameData( xOldId
, xNewId
);
1393 // Adapt Additional Core Properties.
1394 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1395 xNewId
->getContentIdentifier(),
1400 // Do not set new title!
1401 aNewTitle
= rtl::OUString();
1404 aRet
[ nTitlePos
] <<= uno::Exception(
1405 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Exchange failed!")),
1406 static_cast< cppu::OWeakObject
* >( this ) );
1410 if ( !aNewTitle
.isEmpty() )
1412 aEvent
.PropertyName
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title"));
1413 aEvent
.OldValue
= uno::makeAny( m_aProps
.aTitle
);
1414 aEvent
.NewValue
= uno::makeAny( aNewTitle
);
1416 m_aProps
.aTitle
= aNewTitle
;
1418 aChanges
.getArray()[ nChanged
] = aEvent
;
1424 // Save changes, if content was already made persistent.
1425 if ( ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
) ||
1426 ( bStore
&& ( m_eState
== PERSISTENT
) ) )
1428 if ( !storeData( uno::Reference
< io::XInputStream
>() ) )
1432 beans::PropertyValue(
1433 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1436 uno::makeAny(m_xIdentifier
->
1437 getContentIdentifier()),
1438 beans::PropertyState_DIRECT_VALUE
));
1439 ucbhelper::cancelCommandExecution(
1440 ucb::IOErrorCode_CANT_WRITE
,
1441 uno::Sequence
< uno::Any
>(&aProps
, 1),
1443 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1444 "Cannot store persistent data!" )),
1451 aChanges
.realloc( nChanged
);
1452 notifyPropertiesChange( aChanges
);
1458 //=========================================================================
1459 uno::Any
Content::open(
1460 const ucb::OpenCommandArgument2
& rArg
,
1461 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1462 throw( uno::Exception
)
1464 if ( rArg
.Mode
== ucb::OpenMode::ALL
||
1465 rArg
.Mode
== ucb::OpenMode::FOLDERS
||
1466 rArg
.Mode
== ucb::OpenMode::DOCUMENTS
)
1468 //////////////////////////////////////////////////////////////////
1469 // open command for a folder content
1470 //////////////////////////////////////////////////////////////////
1472 uno::Reference
< ucb::XDynamicResultSet
> xSet
1473 = new DynamicResultSet( m_xSMgr
, this, rArg
, xEnv
);
1474 return uno::makeAny( xSet
);
1478 //////////////////////////////////////////////////////////////////
1479 // open command for a document content
1480 //////////////////////////////////////////////////////////////////
1482 if ( ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE
) ||
1483 ( rArg
.Mode
== ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE
) )
1485 // Currently(?) unsupported.
1486 ucbhelper::cancelCommandExecution(
1487 uno::makeAny( ucb::UnsupportedOpenModeException(
1489 static_cast< cppu::OWeakObject
* >( this ),
1490 sal_Int16( rArg
.Mode
) ) ),
1495 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
1496 uno::Reference
< io::XOutputStream
> xOut( rArg
.Sink
, uno::UNO_QUERY
);
1499 // PUSH: write data into xOut
1501 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1504 // No interaction if we are not persistent!
1507 beans::PropertyValue(
1508 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1511 uno::makeAny(m_xIdentifier
->
1512 getContentIdentifier()),
1513 beans::PropertyState_DIRECT_VALUE
));
1514 ucbhelper::cancelCommandExecution(
1515 ucb::IOErrorCode_CANT_READ
,
1516 uno::Sequence
< uno::Any
>(&aProps
, 1),
1517 m_eState
== PERSISTENT
1519 : uno::Reference
< ucb::XCommandEnvironment
>(),
1520 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Got no data stream!")),
1527 uno::Sequence
< sal_Int8
> aBuffer
;
1528 sal_Int32 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1532 aBuffer
.realloc( nRead
);
1533 xOut
->writeBytes( aBuffer
);
1534 aBuffer
.realloc( 0 );
1535 nRead
= xIn
->readSomeBytes( aBuffer
, 65536 );
1538 xOut
->closeOutput();
1540 catch ( io::NotConnectedException
const & )
1542 // closeOutput, readSomeBytes, writeBytes
1544 catch ( io::BufferSizeExceededException
const & )
1546 // closeOutput, readSomeBytes, writeBytes
1548 catch ( io::IOException
const & )
1550 // closeOutput, readSomeBytes, writeBytes
1555 uno::Reference
< io::XActiveDataSink
> xDataSink(
1556 rArg
.Sink
, uno::UNO_QUERY
);
1557 if ( xDataSink
.is() )
1559 // PULL: wait for client read
1561 uno::Reference
< io::XInputStream
> xIn
= getInputStream();
1564 // No interaction if we are not persistent!
1567 beans::PropertyValue(
1568 rtl::OUString( "Uri"),
1570 uno::makeAny(m_xIdentifier
->
1571 getContentIdentifier()),
1572 beans::PropertyState_DIRECT_VALUE
));
1573 ucbhelper::cancelCommandExecution(
1574 ucb::IOErrorCode_CANT_READ
,
1575 uno::Sequence
< uno::Any
>(&aProps
, 1),
1576 m_eState
== PERSISTENT
1579 ucb::XCommandEnvironment
>(),
1580 rtl::OUString( "Got no data stream!" ),
1586 xDataSink
->setInputStream( xIn
);
1590 // Note: aOpenCommand.Sink may contain an XStream
1591 // implementation. Support for this type of
1592 // sink is optional...
1593 ucbhelper::cancelCommandExecution(
1595 ucb::UnsupportedDataSinkException(
1597 static_cast< cppu::OWeakObject
* >( this ),
1608 //=========================================================================
1609 void Content::insert(
1610 const uno::Reference
< io::XInputStream
>& xStream
,
1611 sal_Int32 nNameClashResolve
,
1612 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1613 throw( uno::Exception
)
1615 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1617 // Check, if all required properties were set.
1622 if ( m_aProps
.aTitle
.isEmpty() )
1623 m_aProps
.aTitle
= m_aUri
.getName();
1627 // Required: rArg.Data
1629 if ( !xStream
.is() )
1631 ucbhelper::cancelCommandExecution(
1632 uno::makeAny( ucb::MissingInputStreamException(
1634 static_cast< cppu::OWeakObject
* >( this ) ) ),
1641 if ( m_aProps
.aTitle
.isEmpty() )
1642 m_aProps
.aTitle
= m_aUri
.getName();
1645 rtl::OUString aNewURL
= m_aUri
.getParentUri();
1646 if (1 + aNewURL
.lastIndexOf('/') != aNewURL
.getLength())
1647 aNewURL
+= rtl::OUString("/");
1648 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( m_aProps
.aTitle
);
1649 PackageUri
aNewUri( aNewURL
);
1651 // Handle possible name clash...
1652 switch ( nNameClashResolve
)
1655 case ucb::NameClash::ERROR
:
1656 if ( hasData( aNewUri
) )
1658 ucbhelper::cancelCommandExecution(
1659 uno::makeAny( ucb::NameClashException(
1661 static_cast< cppu::OWeakObject
* >( this ),
1662 task::InteractionClassification_ERROR
,
1663 m_aProps
.aTitle
) ),
1669 // replace (possibly) existing object.
1670 case ucb::NameClash::OVERWRITE
:
1673 // "invent" a new valid title.
1674 case ucb::NameClash::RENAME
:
1675 if ( hasData( aNewUri
) )
1681 rtl::OUString aNew
= aNewUri
.getUri();
1682 aNew
+= rtl::OUString("_");
1683 aNew
+= rtl::OUString::valueOf( ++nTry
);
1684 aNewUri
.setUri( aNew
);
1686 while ( hasData( aNewUri
) && ( nTry
< 1000 ) );
1690 ucbhelper::cancelCommandExecution(
1692 ucb::UnsupportedNameClashException(
1693 rtl::OUString( "Unable to resolve name clash!" ),
1694 static_cast< cppu::OWeakObject
* >( this ),
1695 nNameClashResolve
) ),
1701 m_aProps
.aTitle
+= rtl::OUString("_");
1702 m_aProps
.aTitle
+= rtl::OUString::valueOf( nTry
);
1707 case ucb::NameClash::KEEP
: // deprecated
1708 case ucb::NameClash::ASK
:
1710 if ( hasData( aNewUri
) )
1712 ucbhelper::cancelCommandExecution(
1714 ucb::UnsupportedNameClashException(
1716 static_cast< cppu::OWeakObject
* >( this ),
1717 nNameClashResolve
) ),
1724 // Identifier changed?
1725 sal_Bool bNewId
= ( m_aUri
.getUri() != aNewUri
.getUri() );
1729 m_xIdentifier
= new ::ucbhelper::ContentIdentifier( m_xSMgr
, aNewURL
);
1733 if ( !storeData( xStream
) )
1736 = uno::makeAny(beans::PropertyValue(
1737 rtl::OUString( "Uri"),
1739 uno::makeAny(m_xIdentifier
->
1740 getContentIdentifier()),
1741 beans::PropertyState_DIRECT_VALUE
));
1742 ucbhelper::cancelCommandExecution(
1743 ucb::IOErrorCode_CANT_WRITE
,
1744 uno::Sequence
< uno::Any
>(&aProps
, 1),
1746 rtl::OUString("Cannot store persistent data!"),
1751 m_eState
= PERSISTENT
;
1755 // Take over correct default values from underlying packager...
1756 uno::Reference
< container::XHierarchicalNameAccess
> xXHierarchicalNameAccess
;
1757 loadData( m_pProvider
,
1760 xXHierarchicalNameAccess
);
1767 //=========================================================================
1768 void Content::destroy(
1769 sal_Bool bDeletePhysical
,
1770 const uno::Reference
< ucb::XCommandEnvironment
>& xEnv
)
1771 throw( uno::Exception
)
1773 // @@@ take care about bDeletePhysical -> trashcan support
1775 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1777 uno::Reference
< ucb::XContent
> xThis
= this;
1780 if ( m_eState
!= PERSISTENT
)
1782 ucbhelper::cancelCommandExecution(
1783 uno::makeAny( ucb::UnsupportedCommandException(
1784 rtl::OUString( "Not persistent!" ),
1785 static_cast< cppu::OWeakObject
* >( this ) ) ),
1797 // Process instanciated children...
1799 ContentRefList aChildren
;
1800 queryChildren( aChildren
);
1802 ContentRefList::const_iterator it
= aChildren
.begin();
1803 ContentRefList::const_iterator end
= aChildren
.end();
1807 (*it
)->destroy( bDeletePhysical
, xEnv
);
1813 //=========================================================================
1814 void Content::transfer(
1815 const ucb::TransferInfo
& rInfo
,
1816 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1817 throw( uno::Exception
)
1819 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1822 if ( m_eState
!= PERSISTENT
)
1824 ucbhelper::cancelCommandExecution(
1825 uno::makeAny( ucb::UnsupportedCommandException(
1826 rtl::OUString( "Not persistent!" ),
1827 static_cast< cppu::OWeakObject
* >( this ) ) ),
1832 // Is source a package content?
1833 if ( ( rInfo
.SourceURL
.isEmpty() ) ||
1834 ( rInfo
.SourceURL
.compareTo(
1835 m_aUri
.getUri(), PACKAGE_URL_SCHEME_LENGTH
+ 3 ) != 0 ) )
1837 ucbhelper::cancelCommandExecution(
1838 uno::makeAny( ucb::InteractiveBadTransferURLException(
1840 static_cast< cppu::OWeakObject
* >( this ) ) ),
1845 // Is source not a parent of me / not me?
1846 rtl::OUString aId
= m_aUri
.getParentUri();
1847 aId
+= rtl::OUString("/");
1849 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1852 rInfo
.SourceURL
, rInfo
.SourceURL
.getLength() ) == 0 )
1855 = uno::makeAny(beans::PropertyValue(
1856 rtl::OUString( "Uri"),
1858 uno::makeAny(rInfo
.SourceURL
),
1859 beans::PropertyState_DIRECT_VALUE
));
1860 ucbhelper::cancelCommandExecution(
1861 ucb::IOErrorCode_RECURSIVE
,
1862 uno::Sequence
< uno::Any
>(&aProps
, 1),
1864 rtl::OUString( "Target is equal to or is a child of source!" ),
1870 //////////////////////////////////////////////////////////////////////
1871 // 0) Obtain content object for source.
1872 //////////////////////////////////////////////////////////////////////
1874 uno::Reference
< ucb::XContentIdentifier
> xId
1875 = new ::ucbhelper::ContentIdentifier( m_xSMgr
, rInfo
.SourceURL
);
1877 // Note: The static cast is okay here, because its sure that
1878 // m_xProvider is always the PackageContentProvider.
1879 rtl::Reference
< Content
> xSource
;
1883 xSource
= static_cast< Content
* >(
1884 m_xProvider
->queryContent( xId
).get() );
1886 catch ( ucb::IllegalIdentifierException
const & )
1891 if ( !xSource
.is() )
1894 = uno::makeAny(beans::PropertyValue(
1895 rtl::OUString( "Uri"),
1897 uno::makeAny(xId
->getContentIdentifier()),
1898 beans::PropertyState_DIRECT_VALUE
));
1899 ucbhelper::cancelCommandExecution(
1900 ucb::IOErrorCode_CANT_READ
,
1901 uno::Sequence
< uno::Any
>(&aProps
, 1),
1903 rtl::OUString( "Cannot instanciate source object!" ),
1908 //////////////////////////////////////////////////////////////////////
1909 // 1) Create new child content.
1910 //////////////////////////////////////////////////////////////////////
1912 rtl::OUString aType
= xSource
->isFolder()
1913 ? getContentType( m_aUri
.getScheme(), sal_True
)
1914 : getContentType( m_aUri
.getScheme(), sal_False
);
1915 ucb::ContentInfo aContentInfo
;
1916 aContentInfo
.Type
= aType
;
1917 aContentInfo
.Attributes
= 0;
1919 // Note: The static cast is okay here, because its sure that
1920 // createNewContent always creates a Content.
1921 rtl::Reference
< Content
> xTarget
1922 = static_cast< Content
* >( createNewContent( aContentInfo
).get() );
1923 if ( !xTarget
.is() )
1926 = uno::makeAny(beans::PropertyValue(
1927 rtl::OUString( "Folder"),
1930 beans::PropertyState_DIRECT_VALUE
));
1931 ucbhelper::cancelCommandExecution(
1932 ucb::IOErrorCode_CANT_CREATE
,
1933 uno::Sequence
< uno::Any
>(&aProps
, 1),
1935 rtl::OUString( "XContentCreator::createNewContent failed!" ),
1940 //////////////////////////////////////////////////////////////////////
1941 // 2) Copy data from source content to child content.
1942 //////////////////////////////////////////////////////////////////////
1944 uno::Sequence
< beans::Property
> aSourceProps
1945 = xSource
->getPropertySetInfo( xEnv
)->getProperties();
1946 sal_Int32 nCount
= aSourceProps
.getLength();
1950 sal_Bool bHadTitle
= rInfo
.NewTitle
.isEmpty();
1952 // Get all source values.
1953 uno::Reference
< sdbc::XRow
> xRow
1954 = xSource
->getPropertyValues( aSourceProps
);
1956 uno::Sequence
< beans::PropertyValue
> aValues( nCount
);
1957 beans::PropertyValue
* pValues
= aValues
.getArray();
1959 const beans::Property
* pProps
= aSourceProps
.getConstArray();
1960 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1962 const beans::Property
& rProp
= pProps
[ n
];
1963 beans::PropertyValue
& rValue
= pValues
[ n
];
1965 rValue
.Name
= rProp
.Name
;
1966 rValue
.Handle
= rProp
.Handle
;
1968 if ( !bHadTitle
&& rProp
.Name
== "Title" )
1970 // Set new title instead of original.
1971 bHadTitle
= sal_True
;
1972 rValue
.Value
<<= rInfo
.NewTitle
;
1976 = xRow
->getObject( n
+ 1,
1978 container::XNameAccess
>() );
1980 rValue
.State
= beans::PropertyState_DIRECT_VALUE
;
1982 if ( rProp
.Attributes
& beans::PropertyAttribute::REMOVABLE
)
1984 // Add Additional Core Property.
1987 xTarget
->addProperty( rProp
.Name
,
1991 catch ( beans::PropertyExistException
const & )
1994 catch ( beans::IllegalTypeException
const & )
1997 catch ( lang::IllegalArgumentException
const & )
2003 // Set target values.
2004 xTarget
->setPropertyValues( aValues
, xEnv
);
2007 //////////////////////////////////////////////////////////////////////
2008 // 3) Commit (insert) child.
2009 //////////////////////////////////////////////////////////////////////
2011 xTarget
->insert( xSource
->getInputStream(), rInfo
.NameClash
, xEnv
);
2013 //////////////////////////////////////////////////////////////////////
2014 // 4) Transfer (copy) children of source.
2015 //////////////////////////////////////////////////////////////////////
2017 if ( xSource
->isFolder() )
2019 uno::Reference
< container::XEnumeration
> xIter
2020 = xSource
->getIterator();
2023 while ( xIter
->hasMoreElements() )
2027 uno::Reference
< container::XNamed
> xNamed
;
2028 xIter
->nextElement() >>= xNamed
;
2032 OSL_FAIL( "Content::transfer - Got no XNamed!" );
2036 rtl::OUString aName
= xNamed
->getName();
2038 if ( aName
.isEmpty() )
2040 OSL_FAIL( "Content::transfer - Empty name!" );
2044 rtl::OUString aChildId
= xId
->getContentIdentifier();
2045 if ( ( aChildId
.lastIndexOf( '/' ) + 1 )
2046 != aChildId
.getLength() )
2047 aChildId
+= rtl::OUString("/");
2049 aChildId
+= ::ucb_impl::urihelper::encodeSegment( aName
);
2051 ucb::TransferInfo aInfo
;
2052 aInfo
.MoveData
= sal_False
;
2053 aInfo
.NewTitle
= rtl::OUString();
2054 aInfo
.SourceURL
= aChildId
;
2055 aInfo
.NameClash
= rInfo
.NameClash
;
2057 // Transfer child to target.
2058 xTarget
->transfer( aInfo
, xEnv
);
2060 catch ( container::NoSuchElementException
const & )
2063 catch ( lang::WrappedTargetException
const & )
2070 //////////////////////////////////////////////////////////////////////
2071 // 5) Destroy source ( when moving only ) .
2072 //////////////////////////////////////////////////////////////////////
2074 if ( rInfo
.MoveData
)
2076 xSource
->destroy( sal_True
, xEnv
);
2078 // Remove all persistent data of source and its children.
2079 if ( !xSource
->removeData() )
2083 beans::PropertyValue(
2084 rtl::OUString( "Uri"),
2087 xSource
->m_xIdentifier
->
2088 getContentIdentifier()),
2089 beans::PropertyState_DIRECT_VALUE
));
2090 ucbhelper::cancelCommandExecution(
2091 ucb::IOErrorCode_CANT_WRITE
,
2092 uno::Sequence
< uno::Any
>(&aProps
, 1),
2094 rtl::OUString( "Cannot remove persistent data of source object!" ),
2099 // Remove own and all children's Additional Core Properties.
2100 xSource
->removeAdditionalPropertySet( sal_True
);
2104 //=========================================================================
2105 sal_Bool
Content::exchangeIdentity(
2106 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2111 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
2113 uno::Reference
< ucb::XContent
> xThis
= this;
2115 // Already persistent?
2116 if ( m_eState
!= PERSISTENT
)
2118 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2122 // Exchange own identitity.
2124 // Fail, if a content with given id already exists.
2125 PackageUri
aNewUri( xNewId
->getContentIdentifier() );
2126 if ( !hasData( aNewUri
) )
2128 rtl::OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
2131 if ( exchange( xNewId
) )
2136 // Process instanciated children...
2138 ContentRefList aChildren
;
2139 queryChildren( aChildren
);
2141 ContentRefList::const_iterator it
= aChildren
.begin();
2142 ContentRefList::const_iterator end
= aChildren
.end();
2146 ContentRef xChild
= (*it
);
2148 // Create new content identifier for the child...
2149 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
2150 = xChild
->getIdentifier();
2151 rtl::OUString aOldChildURL
2152 = xOldChildId
->getContentIdentifier();
2153 rtl::OUString aNewChildURL
2154 = aOldChildURL
.replaceAt(
2156 aOldURL
.getLength(),
2157 xNewId
->getContentIdentifier() );
2158 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
2159 = new ::ucbhelper::ContentIdentifier(
2160 m_xSMgr
, aNewChildURL
);
2162 if ( !xChild
->exchangeIdentity( xNewChildId
) )
2172 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2176 //=========================================================================
2177 void Content::queryChildren( ContentRefList
& rChildren
)
2179 // Obtain a list with a snapshot of all currently instanciated contents
2180 // from provider and extract the contents which are direct children
2183 ::ucbhelper::ContentRefList aAllContents
;
2184 m_xProvider
->queryExistingContents( aAllContents
);
2186 rtl::OUString aURL
= m_xIdentifier
->getContentIdentifier();
2188 OSL_ENSURE( aURL
.lastIndexOf( '/' ) != ( aURL
.getLength() - 1 ),
2189 "Content::queryChildren - Invalid URL!" );
2191 aURL
+= rtl::OUString("/");
2193 sal_Int32 nLen
= aURL
.getLength();
2195 ::ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
2196 ::ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
2200 ::ucbhelper::ContentImplHelperRef xChild
= (*it
);
2201 rtl::OUString aChildURL
2202 = xChild
->getIdentifier()->getContentIdentifier();
2204 // Is aURL a prefix of aChildURL?
2205 if ( ( aChildURL
.getLength() > nLen
) &&
2206 ( aChildURL
.compareTo( aURL
, nLen
) == 0 ) )
2208 if ( aChildURL
.indexOf( '/', nLen
) == -1 )
2210 // No further slashes. It's a child!
2211 rChildren
.push_back(
2213 static_cast< Content
* >( xChild
.get() ) ) );
2220 //=========================================================================
2221 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage(
2222 const PackageUri
& rURI
)
2224 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2226 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2227 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2229 if ( !m_xPackage
.is() )
2230 m_xPackage
= m_pProvider
->createPackage( m_aUri
.getPackage(), m_aUri
.getParam() );
2235 return m_pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2238 //=========================================================================
2239 uno::Reference
< container::XHierarchicalNameAccess
> Content::getPackage()
2241 return getPackage( m_aUri
);
2244 //=========================================================================
2246 sal_Bool
Content::hasData(
2247 ContentProvider
* pProvider
,
2248 const PackageUri
& rURI
,
2249 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2251 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2252 if ( !rxPackage
.is() )
2255 return rxPackage
->hasByHierarchicalName( rURI
.getPath() );
2258 //=========================================================================
2259 sal_Bool
Content::hasData( const PackageUri
& rURI
)
2261 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2263 uno::Reference
< container::XHierarchicalNameAccess
> xPackage
;
2264 if ( rURI
.getPackage() == m_aUri
.getPackage() )
2266 xPackage
= getPackage();
2267 if ( !xPackage
.is() )
2270 return xPackage
->hasByHierarchicalName( rURI
.getPath() );
2273 return hasData( m_pProvider
, rURI
, xPackage
);
2276 //=========================================================================
2278 sal_Bool
Content::loadData(
2279 ContentProvider
* pProvider
,
2280 const PackageUri
& rURI
,
2281 ContentProperties
& rProps
,
2282 uno::Reference
< container::XHierarchicalNameAccess
> & rxPackage
)
2284 rxPackage
= pProvider
->createPackage( rURI
.getPackage(), rURI
.getParam() );
2285 if ( !rxPackage
.is() )
2288 if ( rURI
.isRootFolder() )
2290 // Properties available only from package
2291 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2292 rxPackage
, uno::UNO_QUERY
);
2294 OSL_ENSURE( xPackagePropSet
.is(),
2295 "Content::loadData - "
2296 "Got no XPropertySet interface from package!" );
2298 if ( xPackagePropSet
.is() )
2300 // HasEncryptedEntries ( only avalibale at root folder )
2303 uno::Any aHasEncryptedEntries
2304 = xPackagePropSet
->getPropertyValue(
2305 rtl::OUString( "HasEncryptedEntries" ) );
2306 if ( !( aHasEncryptedEntries
>>= rProps
.bHasEncryptedEntries
) )
2308 OSL_FAIL( "Content::loadData - "
2309 "Got no HasEncryptedEntries value!" );
2313 catch ( beans::UnknownPropertyException
const & )
2315 OSL_FAIL( "Content::loadData - "
2316 "Got no HasEncryptedEntries value!" );
2319 catch ( lang::WrappedTargetException
const & )
2321 OSL_FAIL( "Content::loadData - "
2322 "Got no HasEncryptedEntries value!" );
2328 if ( !rxPackage
->hasByHierarchicalName( rURI
.getPath() ) )
2333 uno::Any aEntry
= rxPackage
->getByHierarchicalName( rURI
.getPath() );
2334 if ( aEntry
.hasValue() )
2336 uno::Reference
< beans::XPropertySet
> xPropSet
;
2337 aEntry
>>= xPropSet
;
2339 if ( !xPropSet
.is() )
2341 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2346 rProps
.aTitle
= rURI
.getName();
2352 = xPropSet
->getPropertyValue(
2353 rtl::OUString("MediaType") );
2354 if ( !( aMediaType
>>= rProps
.aMediaType
) )
2356 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2360 catch ( beans::UnknownPropertyException
const & )
2362 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2365 catch ( lang::WrappedTargetException
const & )
2367 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2371 uno::Reference
< container::XEnumerationAccess
> xEnumAccess
;
2372 aEntry
>>= xEnumAccess
;
2374 // ContentType / IsFolder / IsDocument
2375 if ( xEnumAccess
.is() )
2378 rProps
.aContentType
= getContentType( rURI
.getScheme(), sal_True
);
2379 rProps
.bIsDocument
= sal_False
;
2380 rProps
.bIsFolder
= sal_True
;
2385 rProps
.aContentType
= getContentType( rURI
.getScheme(), sal_False
);
2386 rProps
.bIsDocument
= sal_True
;
2387 rProps
.bIsFolder
= sal_False
;
2390 if ( rProps
.bIsDocument
)
2392 // Size ( only available for streams )
2396 = xPropSet
->getPropertyValue(
2397 rtl::OUString("Size") );
2398 if ( !( aSize
>>= rProps
.nSize
) )
2400 OSL_FAIL( "Content::loadData - Got no Size value!" );
2404 catch ( beans::UnknownPropertyException
const & )
2406 OSL_FAIL( "Content::loadData - Got no Size value!" );
2409 catch ( lang::WrappedTargetException
const & )
2411 OSL_FAIL( "Content::loadData - Got no Size value!" );
2415 // Compressed ( only available for streams )
2418 uno::Any aCompressed
2419 = xPropSet
->getPropertyValue(
2420 rtl::OUString("Compressed") );
2421 if ( !( aCompressed
>>= rProps
.bCompressed
) )
2423 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2427 catch ( beans::UnknownPropertyException
const & )
2429 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2432 catch ( lang::WrappedTargetException
const & )
2434 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2438 // Encrypted ( only available for streams )
2442 = xPropSet
->getPropertyValue(
2443 rtl::OUString("Encrypted") );
2444 if ( !( aEncrypted
>>= rProps
.bEncrypted
) )
2446 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2450 catch ( beans::UnknownPropertyException
const & )
2452 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2455 catch ( lang::WrappedTargetException
const & )
2457 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2464 catch ( container::NoSuchElementException
const & )
2466 // getByHierarchicalName
2472 //=========================================================================
2473 sal_Bool
Content::renameData(
2474 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
2475 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
2477 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2479 PackageUri
aURI( xOldId
->getContentIdentifier() );
2480 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage(
2485 if ( !xNA
->hasByHierarchicalName( aURI
.getPath() ) )
2490 uno::Any aEntry
= xNA
->getByHierarchicalName( aURI
.getPath() );
2491 uno::Reference
< container::XNamed
> xNamed
;
2496 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2500 PackageUri
aNewURI( xNewId
->getContentIdentifier() );
2502 // No success indicator!? No return value / exceptions specified.
2503 xNamed
->setName( aNewURI
.getName() );
2507 catch ( container::NoSuchElementException
const & )
2509 // getByHierarchicalName
2515 //=========================================================================
2516 sal_Bool
Content::storeData( const uno::Reference
< io::XInputStream
>& xStream
)
2518 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2520 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2524 uno::Reference
< beans::XPropertySet
> xPackagePropSet(
2525 xNA
, uno::UNO_QUERY
);
2526 OSL_ENSURE( xPackagePropSet
.is(),
2527 "Content::storeData - "
2528 "Got no XPropertySet interface from package!" );
2530 if ( !xPackagePropSet
.is() )
2533 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2535 if ( m_aUri
.isRootFolder() )
2537 // Property available only from package and from streams (see below)
2540 xPackagePropSet
->setPropertyValue(
2541 rtl::OUString("EncryptionKey"),
2542 uno::makeAny( m_aProps
.aEncryptionKey
) );
2543 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2545 catch ( beans::UnknownPropertyException
const & )
2549 catch ( beans::PropertyVetoException
const & )
2553 catch ( lang::IllegalArgumentException
const & )
2557 catch ( lang::WrappedTargetException
const & )
2564 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2571 // Create new resource...
2572 uno::Reference
< lang::XSingleServiceFactory
> xFac(
2573 xNA
, uno::UNO_QUERY
);
2576 OSL_FAIL( "Content::storeData - "
2577 "Got no XSingleServiceFactory interface!" );
2581 uno::Sequence
< uno::Any
> aArgs( 1 );
2582 aArgs
[ 0 ] <<= isFolder();
2584 uno::Reference
< uno::XInterface
> xNew
2585 = xFac
->createInstanceWithArguments( aArgs
);
2589 OSL_FAIL( "Content::storeData - createInstance failed!" );
2593 PackageUri
aParentUri( getParentURL() );
2595 = xNA
->getByHierarchicalName( aParentUri
.getPath() );
2596 uno::Reference
< container::XNameContainer
> xParentContainer
;
2597 aEntry
>>= xParentContainer
;
2599 if ( !xParentContainer
.is() )
2601 OSL_FAIL( "Content::storeData - "
2602 "Got no XNameContainer interface!" );
2606 xParentContainer
->insertByName( m_aProps
.aTitle
,
2607 uno::makeAny( xNew
) );
2609 catch ( uno::RuntimeException
const & )
2613 catch ( lang::IllegalArgumentException
const & )
2616 OSL_FAIL( "Content::storeData - insertByName failed!" );
2619 catch ( container::ElementExistException
const & )
2622 OSL_FAIL( "Content::storeData - insertByName failed!" );
2625 catch ( lang::WrappedTargetException
const & )
2628 OSL_FAIL( "Content::storeData - insertByName failed!" );
2631 catch ( container::NoSuchElementException
const & )
2633 // getByHierarchicalName
2634 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2637 catch ( uno::Exception
const & )
2639 // createInstanceWithArguments
2640 OSL_FAIL( "Content::storeData - Error!" );
2645 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2650 uno::Reference
< beans::XPropertySet
> xPropSet
;
2651 xNA
->getByHierarchicalName( m_aUri
.getPath() ) >>= xPropSet
;
2653 if ( !xPropSet
.is() )
2655 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2659 //////////////////////////////////////////////////////////////////
2660 // Store property values...
2661 //////////////////////////////////////////////////////////////////
2663 if ( m_nModifiedProps
& MEDIATYPE_MODIFIED
)
2665 xPropSet
->setPropertyValue(
2666 rtl::OUString("MediaType"),
2667 uno::makeAny( m_aProps
.aMediaType
) );
2668 m_nModifiedProps
&= ~MEDIATYPE_MODIFIED
;
2671 if ( m_nModifiedProps
& COMPRESSED_MODIFIED
)
2674 xPropSet
->setPropertyValue(
2675 rtl::OUString("Compressed"),
2676 uno::makeAny( m_aProps
.bCompressed
) );
2678 m_nModifiedProps
&= ~COMPRESSED_MODIFIED
;
2681 if ( m_nModifiedProps
& ENCRYPTED_MODIFIED
)
2684 xPropSet
->setPropertyValue(
2685 rtl::OUString("Encrypted"),
2686 uno::makeAny( m_aProps
.bEncrypted
) );
2688 m_nModifiedProps
&= ~ENCRYPTED_MODIFIED
;
2691 if ( m_nModifiedProps
& ENCRYPTIONKEY_MODIFIED
)
2694 xPropSet
->setPropertyValue(
2695 rtl::OUString("EncryptionKey"),
2696 uno::makeAny( m_aProps
.aEncryptionKey
) );
2698 m_nModifiedProps
&= ~ENCRYPTIONKEY_MODIFIED
;
2701 //////////////////////////////////////////////////////////////////
2702 // Store data stream...
2703 //////////////////////////////////////////////////////////////////
2705 if ( xStream
.is() && !isFolder() )
2707 uno::Reference
< io::XActiveDataSink
> xSink(
2708 xPropSet
, uno::UNO_QUERY
);
2712 OSL_FAIL( "Content::storeData - "
2713 "Got no XActiveDataSink interface!" );
2717 xSink
->setInputStream( xStream
);
2722 catch ( container::NoSuchElementException
const & )
2724 // getByHierarchicalName
2726 catch ( beans::UnknownPropertyException
const & )
2730 catch ( beans::PropertyVetoException
const & )
2734 catch ( lang::IllegalArgumentException
const & )
2738 catch ( lang::WrappedTargetException
const & )
2743 OSL_FAIL( "Content::storeData - Error!" );
2747 //=========================================================================
2748 sal_Bool
Content::removeData()
2750 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2752 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2756 PackageUri
aParentUri( getParentURL() );
2757 if ( !xNA
->hasByHierarchicalName( aParentUri
.getPath() ) )
2762 uno::Any aEntry
= xNA
->getByHierarchicalName( aParentUri
.getPath() );
2763 uno::Reference
< container::XNameContainer
> xContainer
;
2764 aEntry
>>= xContainer
;
2766 if ( !xContainer
.is() )
2768 OSL_FAIL( "Content::removeData - "
2769 "Got no XNameContainer interface!" );
2773 xContainer
->removeByName( m_aUri
.getName() );
2776 catch ( container::NoSuchElementException
const & )
2778 // getByHierarchicalName, removeByName
2780 catch ( lang::WrappedTargetException
const & )
2785 OSL_FAIL( "Content::removeData - Error!" );
2789 //=========================================================================
2790 sal_Bool
Content::flushData()
2792 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2794 // Note: XChangesBatch is only implemented by the package itself, not
2795 // by the single entries. Maybe this has to change...
2797 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2801 uno::Reference
< util::XChangesBatch
> xBatch( xNA
, uno::UNO_QUERY
);
2804 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2810 xBatch
->commitChanges();
2813 catch ( lang::WrappedTargetException
const & )
2817 OSL_FAIL( "Content::flushData - Error!" );
2821 //=========================================================================
2822 uno::Reference
< io::XInputStream
> Content::getInputStream()
2824 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2826 uno::Reference
< io::XInputStream
> xStream
;
2827 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2831 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2836 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2837 uno::Reference
< io::XActiveDataSink
> xSink
;
2842 OSL_FAIL( "Content::getInputStream - "
2843 "Got no XActiveDataSink interface!" );
2847 xStream
= xSink
->getInputStream();
2849 OSL_ENSURE( xStream
.is(),
2850 "Content::getInputStream - Got no stream!" );
2852 catch ( container::NoSuchElementException
const & )
2854 // getByHierarchicalName
2860 //=========================================================================
2861 uno::Reference
< container::XEnumeration
> Content::getIterator()
2863 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2865 uno::Reference
< container::XEnumeration
> xIter
;
2866 uno::Reference
< container::XHierarchicalNameAccess
> xNA
= getPackage();
2870 if ( !xNA
->hasByHierarchicalName( m_aUri
.getPath() ) )
2875 uno::Any aEntry
= xNA
->getByHierarchicalName( m_aUri
.getPath() );
2876 uno::Reference
< container::XEnumerationAccess
> xIterFac
;
2877 aEntry
>>= xIterFac
;
2879 if ( !xIterFac
.is() )
2881 OSL_FAIL( "Content::getIterator - "
2882 "Got no XEnumerationAccess interface!" );
2886 xIter
= xIterFac
->createEnumeration();
2888 OSL_ENSURE( xIter
.is(),
2889 "Content::getIterator - Got no iterator!" );
2891 catch ( container::NoSuchElementException
const & )
2893 // getByHierarchicalName
2899 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */