fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucb / source / ucp / package / pkgcontent.cxx
bloba6e2c19fd6114de55ab8cb2113ed9a318500fb58
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
24 *************************************************************************/
25 #include <osl/diagnose.h>
27 #include "osl/doublecheckedlocking.h"
28 #include <rtl/ustring.h>
29 #include <rtl/ustring.hxx>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/beans/PropertyState.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/XPropertyAccess.hpp>
34 #include <com/sun/star/container/XEnumerationAccess.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/lang/IllegalAccessException.hpp>
42 #include <com/sun/star/sdbc/XRow.hpp>
43 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
44 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
45 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
46 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
47 #include <com/sun/star/ucb/NameClash.hpp>
48 #include <com/sun/star/ucb/NameClashException.hpp>
49 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
50 #include <com/sun/star/ucb/OpenMode.hpp>
51 #include <com/sun/star/ucb/TransferInfo.hpp>
52 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
53 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
54 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
55 #include <com/sun/star/ucb/XCommandInfo.hpp>
56 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
57 #include <com/sun/star/util/XChangesBatch.hpp>
58 #include <com/sun/star/uno/Any.hxx>
59 #include <com/sun/star/uno/Sequence.hxx>
60 #include <comphelper/processfactory.hxx>
61 #include <ucbhelper/contentidentifier.hxx>
62 #include <ucbhelper/propertyvalueset.hxx>
63 #include <ucbhelper/cancelcommandexecution.hxx>
64 #include "pkgcontent.hxx"
65 #include "pkgprovider.hxx"
66 #include "pkgresultset.hxx"
68 #include "../inc/urihelper.hxx"
70 using namespace com::sun::star;
71 using namespace package_ucp;
73 #define NONE_MODIFIED sal_uInt32( 0x00 )
74 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
75 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
76 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
77 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
82 // ContentProperties Implementation.
87 ContentProperties::ContentProperties( const OUString& rContentType )
88 : aContentType( rContentType ),
89 nSize( 0 ),
90 bCompressed( true ),
91 bEncrypted( false ),
92 bHasEncryptedEntries( false )
94 bIsFolder = rContentType == PACKAGE_FOLDER_CONTENT_TYPE || rContentType == PACKAGE_ZIP_FOLDER_CONTENT_TYPE;
95 bIsDocument = !bIsFolder;
97 OSL_ENSURE( bIsFolder || rContentType == PACKAGE_STREAM_CONTENT_TYPE || rContentType == PACKAGE_ZIP_STREAM_CONTENT_TYPE,
98 "ContentProperties::ContentProperties - Unknown type!" );
103 uno::Sequence< ucb::ContentInfo >
104 ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
106 if ( bIsFolder )
108 uno::Sequence< beans::Property > aProps( 1 );
109 aProps.getArray()[ 0 ] = beans::Property(
110 OUString("Title"),
112 cppu::UnoType<OUString>::get(),
113 beans::PropertyAttribute::BOUND );
115 uno::Sequence< ucb::ContentInfo > aSeq( 2 );
117 // Folder.
118 aSeq.getArray()[ 0 ].Type
119 = Content::getContentType( rUri.getScheme(), true );
120 aSeq.getArray()[ 0 ].Attributes
121 = ucb::ContentInfoAttribute::KIND_FOLDER;
122 aSeq.getArray()[ 0 ].Properties = aProps;
124 // Stream.
125 aSeq.getArray()[ 1 ].Type
126 = Content::getContentType( rUri.getScheme(), false );
127 aSeq.getArray()[ 1 ].Attributes
128 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
129 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
130 aSeq.getArray()[ 1 ].Properties = aProps;
132 return aSeq;
134 else
136 return uno::Sequence< ucb::ContentInfo >( 0 );
143 // Content Implementation.
148 // static ( "virtual" ctor )
149 Content* Content::create(
150 const uno::Reference< uno::XComponentContext >& rxContext,
151 ContentProvider* pProvider,
152 const uno::Reference< ucb::XContentIdentifier >& Identifier )
154 OUString aURL = Identifier->getContentIdentifier();
155 PackageUri aURI( aURL );
156 ContentProperties aProps;
157 uno::Reference< container::XHierarchicalNameAccess > xPackage;
159 if ( loadData( pProvider, aURI, aProps, xPackage ) )
161 // resource exists
163 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
164 if ( ( nLastSlash + 1 ) == aURL.getLength() )
166 // Client explicitly requested a folder!
167 if ( !aProps.bIsFolder )
168 return 0;
171 uno::Reference< ucb::XContentIdentifier > xId
172 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
173 return new Content( rxContext, pProvider, xId, xPackage, aURI, aProps );
175 else
177 // resource doesn't exist
179 bool bFolder = false;
181 // Guess type according to URI.
182 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
183 if ( ( nLastSlash + 1 ) == aURL.getLength() )
184 bFolder = true;
186 uno::Reference< ucb::XContentIdentifier > xId
187 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
189 ucb::ContentInfo aInfo;
190 if ( bFolder || aURI.isRootFolder() )
191 aInfo.Type = getContentType( aURI.getScheme(), true );
192 else
193 aInfo.Type = getContentType( aURI.getScheme(), false );
195 return new Content( rxContext, pProvider, xId, xPackage, aURI, aInfo );
200 // static ( "virtual" ctor )
201 Content* Content::create(
202 const uno::Reference< uno::XComponentContext >& rxContext,
203 ContentProvider* pProvider,
204 const uno::Reference< ucb::XContentIdentifier >& Identifier,
205 const ucb::ContentInfo& Info )
207 if ( Info.Type.isEmpty() )
208 return 0;
210 PackageUri aURI( Identifier->getContentIdentifier() );
212 if ( !Info.Type.equalsIgnoreAsciiCase(
213 getContentType( aURI.getScheme(), true ) ) &&
214 !Info.Type.equalsIgnoreAsciiCase(
215 getContentType( aURI.getScheme(), false ) ) )
216 return 0;
218 uno::Reference< container::XHierarchicalNameAccess > xPackage;
220 xPackage = pProvider->createPackage( aURI );
222 uno::Reference< ucb::XContentIdentifier > xId
223 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
224 return new Content( rxContext, pProvider, xId, xPackage, aURI, Info );
228 // static
229 OUString Content::getContentType(
230 const OUString& aScheme, bool bFolder )
232 return ( "application/"
233 + aScheme
234 + ( bFolder
235 ? OUString("-folder")
236 : OUString("-stream") ) );
240 Content::Content(
241 const uno::Reference< uno::XComponentContext >& rxContext,
242 ContentProvider* pProvider,
243 const uno::Reference< ucb::XContentIdentifier >& Identifier,
244 const uno::Reference< container::XHierarchicalNameAccess > & Package,
245 const PackageUri& rUri,
246 const ContentProperties& rProps )
247 : ContentImplHelper( rxContext, pProvider, Identifier ),
248 m_aUri( rUri ),
249 m_aProps( rProps ),
250 m_eState( PERSISTENT ),
251 m_xPackage( Package ),
252 m_pProvider( pProvider ),
253 m_nModifiedProps( NONE_MODIFIED )
258 Content::Content(
259 const uno::Reference< uno::XComponentContext >& rxContext,
260 ContentProvider* pProvider,
261 const uno::Reference< ucb::XContentIdentifier >& Identifier,
262 const uno::Reference< container::XHierarchicalNameAccess > & Package,
263 const PackageUri& rUri,
264 const ucb::ContentInfo& Info )
265 : ContentImplHelper( rxContext, pProvider, Identifier ),
266 m_aUri( rUri ),
267 m_aProps( Info.Type ),
268 m_eState( TRANSIENT ),
269 m_xPackage( Package ),
270 m_pProvider( pProvider ),
271 m_nModifiedProps( NONE_MODIFIED )
276 // virtual
277 Content::~Content()
283 // XInterface methods.
287 // virtual
288 void SAL_CALL Content::acquire()
289 throw( )
291 ContentImplHelper::acquire();
295 // virtual
296 void SAL_CALL Content::release()
297 throw( )
299 ContentImplHelper::release();
303 // virtual
304 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
305 throw ( uno::RuntimeException, std::exception )
307 uno::Any aRet;
309 if ( isFolder() )
310 aRet = cppu::queryInterface(
311 rType, static_cast< ucb::XContentCreator * >( this ) );
313 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
318 // XTypeProvider methods.
322 XTYPEPROVIDER_COMMON_IMPL( Content );
325 // virtual
326 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
327 throw( uno::RuntimeException, std::exception )
329 cppu::OTypeCollection * pCollection = 0;
331 if ( isFolder() )
333 static cppu::OTypeCollection* pFolderTypes = 0;
335 pCollection = pFolderTypes;
336 if ( !pCollection )
338 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
340 pCollection = pFolderTypes;
341 if ( !pCollection )
343 static cppu::OTypeCollection aCollection(
344 CPPU_TYPE_REF( lang::XTypeProvider ),
345 CPPU_TYPE_REF( lang::XServiceInfo ),
346 CPPU_TYPE_REF( lang::XComponent ),
347 CPPU_TYPE_REF( ucb::XContent ),
348 CPPU_TYPE_REF( ucb::XCommandProcessor ),
349 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
350 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
351 CPPU_TYPE_REF( beans::XPropertyContainer ),
352 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
353 CPPU_TYPE_REF( container::XChild ),
354 CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
355 pCollection = &aCollection;
356 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
357 pFolderTypes = pCollection;
360 else {
361 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
364 else
366 static cppu::OTypeCollection* pDocumentTypes = 0;
368 pCollection = pDocumentTypes;
369 if ( !pCollection )
371 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
373 pCollection = pDocumentTypes;
374 if ( !pCollection )
376 static cppu::OTypeCollection aCollection(
377 CPPU_TYPE_REF( lang::XTypeProvider ),
378 CPPU_TYPE_REF( lang::XServiceInfo ),
379 CPPU_TYPE_REF( lang::XComponent ),
380 CPPU_TYPE_REF( ucb::XContent ),
381 CPPU_TYPE_REF( ucb::XCommandProcessor ),
382 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
383 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
384 CPPU_TYPE_REF( beans::XPropertyContainer ),
385 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
386 CPPU_TYPE_REF( container::XChild ) );
387 pCollection = &aCollection;
388 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
389 pDocumentTypes = pCollection;
392 else {
393 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
397 return (*pCollection).getTypes();
402 // XServiceInfo methods.
406 // virtual
407 OUString SAL_CALL Content::getImplementationName()
408 throw( uno::RuntimeException, std::exception )
410 return OUString( "com.sun.star.comp.ucb.PackageContent" );
414 // virtual
415 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
416 throw( uno::RuntimeException, std::exception )
418 uno::Sequence< OUString > aSNS( 1 );
419 if ( isFolder() )
420 aSNS.getArray()[ 0 ] = PACKAGE_FOLDER_CONTENT_SERVICE_NAME;
421 else
422 aSNS.getArray()[ 0 ] = PACKAGE_STREAM_CONTENT_SERVICE_NAME;
424 return aSNS;
429 // XContent methods.
433 // virtual
434 OUString SAL_CALL Content::getContentType()
435 throw( uno::RuntimeException, std::exception )
437 return m_aProps.aContentType;
442 // XCommandProcessor methods.
446 // virtual
447 uno::Any SAL_CALL Content::execute(
448 const ucb::Command& aCommand,
449 sal_Int32 /*CommandId*/,
450 const uno::Reference< ucb::XCommandEnvironment >& Environment )
451 throw( uno::Exception,
452 ucb::CommandAbortedException,
453 uno::RuntimeException, std::exception )
455 uno::Any aRet;
457 if ( aCommand.Name == "getPropertyValues" )
460 // getPropertyValues
463 uno::Sequence< beans::Property > Properties;
464 if ( !( aCommand.Argument >>= Properties ) )
466 ucbhelper::cancelCommandExecution(
467 uno::makeAny( lang::IllegalArgumentException(
468 OUString( "Wrong argument type!" ),
469 static_cast< cppu::OWeakObject * >( this ),
470 -1 ) ),
471 Environment );
472 // Unreachable
475 aRet <<= getPropertyValues( Properties );
477 else if ( aCommand.Name == "setPropertyValues" )
480 // setPropertyValues
483 uno::Sequence< beans::PropertyValue > aProperties;
484 if ( !( aCommand.Argument >>= aProperties ) )
486 ucbhelper::cancelCommandExecution(
487 uno::makeAny( lang::IllegalArgumentException(
488 OUString( "Wrong argument type!" ),
489 static_cast< cppu::OWeakObject * >( this ),
490 -1 ) ),
491 Environment );
492 // Unreachable
495 if ( !aProperties.getLength() )
497 ucbhelper::cancelCommandExecution(
498 uno::makeAny( lang::IllegalArgumentException(
499 OUString( "No properties!" ),
500 static_cast< cppu::OWeakObject * >( this ),
501 -1 ) ),
502 Environment );
503 // Unreachable
506 aRet <<= setPropertyValues( aProperties, Environment );
508 else if ( aCommand.Name == "getPropertySetInfo" )
511 // getPropertySetInfo
514 // Note: Implemented by base class.
515 aRet <<= getPropertySetInfo( Environment );
517 else if ( aCommand.Name == "getCommandInfo" )
520 // getCommandInfo
523 // Note: Implemented by base class.
524 aRet <<= getCommandInfo( Environment );
526 else if ( aCommand.Name == "open" )
529 // open
532 ucb::OpenCommandArgument2 aOpenCommand;
533 if ( !( aCommand.Argument >>= aOpenCommand ) )
535 ucbhelper::cancelCommandExecution(
536 uno::makeAny( lang::IllegalArgumentException(
537 OUString( "Wrong argument type!" ),
538 static_cast< cppu::OWeakObject * >( this ),
539 -1 ) ),
540 Environment );
541 // Unreachable
544 aRet = open( aOpenCommand, Environment );
546 else if ( !m_aUri.isRootFolder() && aCommand.Name == "insert" )
549 // insert
552 ucb::InsertCommandArgument aArg;
553 if ( !( aCommand.Argument >>= aArg ) )
555 ucbhelper::cancelCommandExecution(
556 uno::makeAny( lang::IllegalArgumentException(
557 OUString( "Wrong argument type!" ),
558 static_cast< cppu::OWeakObject * >( this ),
559 -1 ) ),
560 Environment );
561 // Unreachable
564 sal_Int32 nNameClash = aArg.ReplaceExisting
565 ? ucb::NameClash::OVERWRITE
566 : ucb::NameClash::ERROR;
567 insert( aArg.Data, nNameClash, Environment );
569 else if ( !m_aUri.isRootFolder() && aCommand.Name == "delete" )
572 // delete
575 bool bDeletePhysical = false;
576 aCommand.Argument >>= bDeletePhysical;
577 destroy( bDeletePhysical, Environment );
579 // Remove own and all children's persistent data.
580 if ( !removeData() )
582 uno::Any aProps
583 = uno::makeAny(
584 beans::PropertyValue(
585 OUString( "Uri"),
587 uno::makeAny(m_xIdentifier->
588 getContentIdentifier()),
589 beans::PropertyState_DIRECT_VALUE));
590 ucbhelper::cancelCommandExecution(
591 ucb::IOErrorCode_CANT_WRITE,
592 uno::Sequence< uno::Any >(&aProps, 1),
593 Environment,
594 OUString( "Cannot remove persistent data!" ),
595 this );
596 // Unreachable
599 // Remove own and all children's Additional Core Properties.
600 removeAdditionalPropertySet( true );
602 else if ( aCommand.Name == "transfer" )
605 // transfer
606 // ( Not available at stream objects )
609 ucb::TransferInfo aInfo;
610 if ( !( aCommand.Argument >>= aInfo ) )
612 ucbhelper::cancelCommandExecution(
613 uno::makeAny( lang::IllegalArgumentException(
614 OUString( "Wrong argument type!" ),
615 static_cast< cppu::OWeakObject * >( this ),
616 -1 ) ),
617 Environment );
618 // Unreachable
621 transfer( aInfo, Environment );
623 else if ( aCommand.Name == "createNewContent" && isFolder() )
626 // createNewContent
627 // ( Not available at stream objects )
630 ucb::ContentInfo aInfo;
631 if ( !( aCommand.Argument >>= aInfo ) )
633 OSL_FAIL( "Wrong argument type!" );
634 ucbhelper::cancelCommandExecution(
635 uno::makeAny( lang::IllegalArgumentException(
636 OUString( "Wrong argument type!" ),
637 static_cast< cppu::OWeakObject * >( this ),
638 -1 ) ),
639 Environment );
640 // Unreachable
643 aRet <<= createNewContent( aInfo );
645 else if ( aCommand.Name == "flush" )
648 // flush
649 // ( Not available at stream objects )
652 if( !flushData() )
654 uno::Any aProps
655 = uno::makeAny(
656 beans::PropertyValue(
657 OUString( "Uri"),
659 uno::makeAny(m_xIdentifier->
660 getContentIdentifier()),
661 beans::PropertyState_DIRECT_VALUE));
662 ucbhelper::cancelCommandExecution(
663 ucb::IOErrorCode_CANT_WRITE,
664 uno::Sequence< uno::Any >(&aProps, 1),
665 Environment,
666 OUString( "Cannot write file to disk!" ),
667 this );
668 // Unreachable
671 else
674 // Unsupported command
677 ucbhelper::cancelCommandExecution(
678 uno::makeAny( ucb::UnsupportedCommandException(
679 OUString(),
680 static_cast< cppu::OWeakObject * >( this ) ) ),
681 Environment );
682 // Unreachable
685 return aRet;
689 // virtual
690 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
691 throw( uno::RuntimeException, std::exception )
693 // @@@ Implement logic to abort running commands, if this makes
694 // sense for your content.
699 // XContentCreator methods.
703 // virtual
704 uno::Sequence< ucb::ContentInfo > SAL_CALL
705 Content::queryCreatableContentsInfo()
706 throw( uno::RuntimeException, std::exception )
708 return m_aProps.getCreatableContentsInfo( m_aUri );
712 // virtual
713 uno::Reference< ucb::XContent > SAL_CALL
714 Content::createNewContent( const ucb::ContentInfo& Info )
715 throw( uno::RuntimeException, std::exception )
717 if ( isFolder() )
719 osl::Guard< osl::Mutex > aGuard( m_aMutex );
721 if ( Info.Type.isEmpty() )
722 return uno::Reference< ucb::XContent >();
724 if ( !Info.Type.equalsIgnoreAsciiCase(
725 getContentType( m_aUri.getScheme(), true ) ) &&
726 !Info.Type.equalsIgnoreAsciiCase(
727 getContentType( m_aUri.getScheme(), false ) ) )
728 return uno::Reference< ucb::XContent >();
730 OUString aURL = m_aUri.getUri();
731 aURL += "/";
733 if ( Info.Type.equalsIgnoreAsciiCase(
734 getContentType( m_aUri.getScheme(), true ) ) )
735 aURL += "New_Folder";
736 else
737 aURL += "New_Stream";
739 uno::Reference< ucb::XContentIdentifier > xId(
740 new ::ucbhelper::ContentIdentifier( aURL ) );
742 return create( m_xContext, m_pProvider, xId, Info );
744 else
746 OSL_FAIL( "createNewContent called on non-folder object!" );
747 return uno::Reference< ucb::XContent >();
753 // Non-interface methods.
757 // virtual
758 OUString Content::getParentURL()
760 return m_aUri.getParentUri();
764 // static
765 uno::Reference< sdbc::XRow > Content::getPropertyValues(
766 const uno::Reference< uno::XComponentContext >& rxContext,
767 const uno::Sequence< beans::Property >& rProperties,
768 ContentProvider* pProvider,
769 const OUString& rContentId )
771 ContentProperties aData;
772 uno::Reference< container::XHierarchicalNameAccess > xPackage;
773 if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) )
775 return getPropertyValues( rxContext,
776 rProperties,
777 aData,
778 rtl::Reference<
779 ::ucbhelper::ContentProviderImplHelper >(
780 pProvider ),
781 rContentId );
783 else
785 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
786 = new ::ucbhelper::PropertyValueSet( rxContext );
788 sal_Int32 nCount = rProperties.getLength();
789 if ( nCount )
791 const beans::Property* pProps = rProperties.getConstArray();
792 for ( sal_Int32 n = 0; n < nCount; ++n )
793 xRow->appendVoid( pProps[ n ] );
796 return uno::Reference< sdbc::XRow >( xRow.get() );
801 // static
802 uno::Reference< sdbc::XRow > Content::getPropertyValues(
803 const uno::Reference< uno::XComponentContext >& rxContext,
804 const uno::Sequence< beans::Property >& rProperties,
805 const ContentProperties& rData,
806 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >&
807 rProvider,
808 const OUString& rContentId )
810 // Note: Empty sequence means "get values of all supported properties".
812 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
813 = new ::ucbhelper::PropertyValueSet( rxContext );
815 sal_Int32 nCount = rProperties.getLength();
816 if ( nCount )
818 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
819 bool bTriedToGetAdditionalPropSet = false;
821 const beans::Property* pProps = rProperties.getConstArray();
822 for ( sal_Int32 n = 0; n < nCount; ++n )
824 const beans::Property& rProp = pProps[ n ];
826 // Process Core properties.
828 if ( rProp.Name == "ContentType" )
830 xRow->appendString ( rProp, rData.aContentType );
832 else if ( rProp.Name == "Title" )
834 xRow->appendString ( rProp, rData.aTitle );
836 else if ( rProp.Name == "IsDocument" )
838 xRow->appendBoolean( rProp, rData.bIsDocument );
840 else if ( rProp.Name == "IsFolder" )
842 xRow->appendBoolean( rProp, rData.bIsFolder );
844 else if ( rProp.Name == "CreatableContentsInfo" )
846 xRow->appendObject(
847 rProp, uno::makeAny(
848 rData.getCreatableContentsInfo(
849 PackageUri( rContentId ) ) ) );
851 else if ( rProp.Name == "MediaType" )
853 xRow->appendString ( rProp, rData.aMediaType );
855 else if ( rProp.Name == "Size" )
857 // Property only available for streams.
858 if ( rData.bIsDocument )
859 xRow->appendLong( rProp, rData.nSize );
860 else
861 xRow->appendVoid( rProp );
863 else if ( rProp.Name == "Compressed" )
865 // Property only available for streams.
866 if ( rData.bIsDocument )
867 xRow->appendBoolean( rProp, rData.bCompressed );
868 else
869 xRow->appendVoid( rProp );
871 else if ( rProp.Name == "Encrypted" )
873 // Property only available for streams.
874 if ( rData.bIsDocument )
875 xRow->appendBoolean( rProp, rData.bEncrypted );
876 else
877 xRow->appendVoid( rProp );
879 else if ( rProp.Name == "HasEncryptedEntries" )
881 // Property only available for root folder.
882 PackageUri aURI( rContentId );
883 if ( aURI.isRootFolder() )
884 xRow->appendBoolean( rProp, rData.bHasEncryptedEntries );
885 else
886 xRow->appendVoid( rProp );
888 else
890 // Not a Core Property! Maybe it's an Additional Core Property?!
892 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
894 xAdditionalPropSet
895 = uno::Reference< beans::XPropertySet >(
896 rProvider->getAdditionalPropertySet( rContentId,
897 false ),
898 uno::UNO_QUERY );
899 bTriedToGetAdditionalPropSet = true;
902 if ( xAdditionalPropSet.is() )
904 if ( !xRow->appendPropertySetValue(
905 xAdditionalPropSet,
906 rProp ) )
908 // Append empty entry.
909 xRow->appendVoid( rProp );
912 else
914 // Append empty entry.
915 xRow->appendVoid( rProp );
920 else
922 // Append all Core Properties.
923 xRow->appendString (
924 beans::Property(
925 OUString("ContentType"),
927 cppu::UnoType<OUString>::get(),
928 beans::PropertyAttribute::BOUND
929 | beans::PropertyAttribute::READONLY ),
930 rData.aContentType );
931 xRow->appendString(
932 beans::Property(
933 OUString("Title"),
935 cppu::UnoType<OUString>::get(),
936 beans::PropertyAttribute::BOUND ),
937 rData.aTitle );
938 xRow->appendBoolean(
939 beans::Property(
940 OUString("IsDocument"),
942 cppu::UnoType<bool>::get(),
943 beans::PropertyAttribute::BOUND
944 | beans::PropertyAttribute::READONLY ),
945 rData.bIsDocument );
946 xRow->appendBoolean(
947 beans::Property(
948 OUString("IsFolder"),
950 cppu::UnoType<bool>::get(),
951 beans::PropertyAttribute::BOUND
952 | beans::PropertyAttribute::READONLY ),
953 rData.bIsFolder );
954 xRow->appendObject(
955 beans::Property(
956 OUString("CreatableContentsInfo"),
958 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
959 beans::PropertyAttribute::BOUND
960 | beans::PropertyAttribute::READONLY ),
961 uno::makeAny(
962 rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
963 xRow->appendString(
964 beans::Property(
965 OUString("MediaType"),
967 cppu::UnoType<OUString>::get(),
968 beans::PropertyAttribute::BOUND ),
969 rData.aMediaType );
971 // Properties only available for streams.
972 if ( rData.bIsDocument )
974 xRow->appendLong(
975 beans::Property(
976 OUString("Size"),
978 cppu::UnoType<sal_Int64>::get(),
979 beans::PropertyAttribute::BOUND
980 | beans::PropertyAttribute::READONLY ),
981 rData.nSize );
983 xRow->appendBoolean(
984 beans::Property(
985 OUString("Compressed"),
987 cppu::UnoType<bool>::get(),
988 beans::PropertyAttribute::BOUND ),
989 rData.bCompressed );
991 xRow->appendBoolean(
992 beans::Property(
993 OUString("Encrypted"),
995 cppu::UnoType<bool>::get(),
996 beans::PropertyAttribute::BOUND ),
997 rData.bEncrypted );
1000 // Properties only available for root folder.
1001 PackageUri aURI( rContentId );
1002 if ( aURI.isRootFolder() )
1004 xRow->appendBoolean(
1005 beans::Property(
1006 OUString("HasEncryptedEntries"),
1008 cppu::UnoType<bool>::get(),
1009 beans::PropertyAttribute::BOUND
1010 | beans::PropertyAttribute::READONLY ),
1011 rData.bHasEncryptedEntries );
1014 // Append all Additional Core Properties.
1016 uno::Reference< beans::XPropertySet > xSet(
1017 rProvider->getAdditionalPropertySet( rContentId, false ),
1018 uno::UNO_QUERY );
1019 xRow->appendPropertySet( xSet );
1022 return uno::Reference< sdbc::XRow >( xRow.get() );
1026 uno::Reference< sdbc::XRow > Content::getPropertyValues(
1027 const uno::Sequence< beans::Property >& rProperties )
1029 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1030 return getPropertyValues( m_xContext,
1031 rProperties,
1032 m_aProps,
1033 rtl::Reference<
1034 ::ucbhelper::ContentProviderImplHelper >(
1035 m_xProvider.get() ),
1036 m_xIdentifier->getContentIdentifier() );
1040 uno::Sequence< uno::Any > Content::setPropertyValues(
1041 const uno::Sequence< beans::PropertyValue >& rValues,
1042 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1043 throw( uno::Exception )
1045 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1047 uno::Sequence< uno::Any > aRet( rValues.getLength() );
1048 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1049 sal_Int32 nChanged = 0;
1051 beans::PropertyChangeEvent aEvent;
1052 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1053 aEvent.Further = sal_False;
1054 // aEvent.PropertyName =
1055 aEvent.PropertyHandle = -1;
1056 // aEvent.OldValue =
1057 // aEvent.NewValue =
1059 const beans::PropertyValue* pValues = rValues.getConstArray();
1060 sal_Int32 nCount = rValues.getLength();
1062 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1063 bool bTriedToGetAdditionalPropSet = false;
1064 bool bExchange = false;
1065 bool bStore = false;
1066 OUString aNewTitle;
1067 sal_Int32 nTitlePos = -1;
1069 for ( sal_Int32 n = 0; n < nCount; ++n )
1071 const beans::PropertyValue& rValue = pValues[ n ];
1073 if ( rValue.Name == "ContentType" )
1075 // Read-only property!
1076 aRet[ n ] <<= lang::IllegalAccessException(
1077 OUString(
1078 "Property is read-only!" ),
1079 static_cast< cppu::OWeakObject * >( this ) );
1081 else if ( rValue.Name == "IsDocument" )
1083 // Read-only property!
1084 aRet[ n ] <<= lang::IllegalAccessException(
1085 OUString(
1086 "Property is read-only!" ),
1087 static_cast< cppu::OWeakObject * >( this ) );
1089 else if ( rValue.Name == "IsFolder" )
1091 // Read-only property!
1092 aRet[ n ] <<= lang::IllegalAccessException(
1093 OUString(
1094 "Property is read-only!" ),
1095 static_cast< cppu::OWeakObject * >( this ) );
1097 else if ( rValue.Name == "CreatableContentsInfo" )
1099 // Read-only property!
1100 aRet[ n ] <<= lang::IllegalAccessException(
1101 OUString(
1102 "Property is read-only!" ),
1103 static_cast< cppu::OWeakObject * >( this ) );
1105 else if ( rValue.Name == "Title" )
1107 if ( m_aUri.isRootFolder() )
1109 // Read-only property!
1110 aRet[ n ] <<= lang::IllegalAccessException(
1111 OUString(
1112 "Property is read-only!" ),
1113 static_cast< cppu::OWeakObject * >( this ) );
1115 else
1117 OUString aNewValue;
1118 if ( rValue.Value >>= aNewValue )
1120 // No empty titles!
1121 if ( !aNewValue.isEmpty() )
1123 if ( aNewValue != m_aProps.aTitle )
1125 // modified title -> modified URL -> exchange !
1126 if ( m_eState == PERSISTENT )
1127 bExchange = true;
1129 // new value will be set later...
1130 aNewTitle = aNewValue;
1132 // remember position within sequence of values
1133 // (for error handling).
1134 nTitlePos = n;
1137 else
1139 aRet[ n ] <<=
1140 lang::IllegalArgumentException(
1141 OUString(
1142 "Empty title not allowed!" ),
1143 static_cast< cppu::OWeakObject * >( this ),
1144 -1 );
1147 else
1149 aRet[ n ] <<=
1150 beans::IllegalTypeException(
1151 OUString(
1152 "Property value has wrong type!" ),
1153 static_cast< cppu::OWeakObject * >( this ) );
1157 else if ( rValue.Name == "MediaType" )
1159 OUString aNewValue;
1160 if ( rValue.Value >>= aNewValue )
1162 if ( aNewValue != m_aProps.aMediaType )
1164 aEvent.PropertyName = rValue.Name;
1165 aEvent.OldValue = uno::makeAny( m_aProps.aMediaType );
1166 aEvent.NewValue = uno::makeAny( aNewValue );
1168 m_aProps.aMediaType = aNewValue;
1169 nChanged++;
1170 bStore = true;
1171 m_nModifiedProps |= MEDIATYPE_MODIFIED;
1174 else
1176 aRet[ n ] <<= beans::IllegalTypeException(
1177 OUString(
1178 "Property value has wrong type!" ),
1179 static_cast< cppu::OWeakObject * >( this ) );
1182 else if ( rValue.Name == "Size" )
1184 // Read-only property!
1185 aRet[ n ] <<= lang::IllegalAccessException(
1186 OUString(
1187 "Property is read-only!" ),
1188 static_cast< cppu::OWeakObject * >( this ) );
1190 else if ( rValue.Name == "Compressed" )
1192 // Property only available for streams.
1193 if ( m_aProps.bIsDocument )
1195 bool bNewValue;
1196 if ( rValue.Value >>= bNewValue )
1198 if ( bNewValue != m_aProps.bCompressed )
1200 aEvent.PropertyName = rValue.Name;
1201 aEvent.OldValue = uno::makeAny( m_aProps.bCompressed );
1202 aEvent.NewValue = uno::makeAny( bNewValue );
1204 m_aProps.bCompressed = bNewValue;
1205 nChanged++;
1206 bStore = true;
1207 m_nModifiedProps |= COMPRESSED_MODIFIED;
1210 else
1212 aRet[ n ] <<= beans::IllegalTypeException(
1213 OUString(
1214 "Property value has wrong type!" ),
1215 static_cast< cppu::OWeakObject * >( this ) );
1218 else
1220 aRet[ n ] <<= beans::UnknownPropertyException(
1221 OUString(
1222 "Compressed only supported by streams!" ),
1223 static_cast< cppu::OWeakObject * >( this ) );
1226 else if ( rValue.Name == "Encrypted" )
1228 // Property only available for streams.
1229 if ( m_aProps.bIsDocument )
1231 bool bNewValue;
1232 if ( rValue.Value >>= bNewValue )
1234 if ( bNewValue != m_aProps.bEncrypted )
1236 aEvent.PropertyName = rValue.Name;
1237 aEvent.OldValue = uno::makeAny( m_aProps.bEncrypted );
1238 aEvent.NewValue = uno::makeAny( bNewValue );
1240 m_aProps.bEncrypted = bNewValue;
1241 nChanged++;
1242 bStore = true;
1243 m_nModifiedProps |= ENCRYPTED_MODIFIED;
1246 else
1248 aRet[ n ] <<= beans::IllegalTypeException(
1249 OUString(
1250 "Property value has wrong type!" ),
1251 static_cast< cppu::OWeakObject * >( this ) );
1254 else
1256 aRet[ n ] <<= beans::UnknownPropertyException(
1257 OUString(
1258 "Encrypted only supported by streams!" ),
1259 static_cast< cppu::OWeakObject * >( this ) );
1262 else if ( rValue.Name == "HasEncryptedEntries" )
1264 // Read-only property!
1265 aRet[ n ] <<= lang::IllegalAccessException(
1266 OUString(
1267 "Property is read-only!" ),
1268 static_cast< cppu::OWeakObject * >( this ) );
1270 else if ( rValue.Name == "EncryptionKey" )
1272 // @@@ This is a temporary solution. In the future submitting
1273 // the key should be done using an interaction handler!
1275 // Write-Only property. Only supported by root folder and streams
1276 // (all non-root folders of a package have the same encryption key).
1277 if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
1279 uno::Sequence < sal_Int8 > aNewValue;
1280 if ( rValue.Value >>= aNewValue )
1282 if ( aNewValue != m_aProps.aEncryptionKey )
1284 aEvent.PropertyName = rValue.Name;
1285 aEvent.OldValue = uno::makeAny(
1286 m_aProps.aEncryptionKey );
1287 aEvent.NewValue = uno::makeAny( aNewValue );
1289 m_aProps.aEncryptionKey = aNewValue;
1290 nChanged++;
1291 bStore = true;
1292 m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
1295 else
1297 aRet[ n ] <<= beans::IllegalTypeException(
1298 OUString(
1299 "Property value has wrong type!" ),
1300 static_cast< cppu::OWeakObject * >( this ) );
1303 else
1305 aRet[ n ] <<= beans::UnknownPropertyException(
1306 OUString(
1307 "EncryptionKey not supported by non-root folder!" ),
1308 static_cast< cppu::OWeakObject * >( this ) );
1311 else
1313 // Not a Core Property! Maybe it's an Additional Core Property?!
1315 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1317 xAdditionalPropSet = getAdditionalPropertySet( false );
1318 bTriedToGetAdditionalPropSet = true;
1321 if ( xAdditionalPropSet.is() )
1325 uno::Any aOldValue
1326 = xAdditionalPropSet->getPropertyValue( rValue.Name );
1327 if ( aOldValue != rValue.Value )
1329 xAdditionalPropSet->setPropertyValue(
1330 rValue.Name, rValue.Value );
1332 aEvent.PropertyName = rValue.Name;
1333 aEvent.OldValue = aOldValue;
1334 aEvent.NewValue = rValue.Value;
1336 aChanges.getArray()[ nChanged ] = aEvent;
1337 nChanged++;
1340 catch ( beans::UnknownPropertyException const & e )
1342 aRet[ n ] <<= e;
1344 catch ( lang::WrappedTargetException const & e )
1346 aRet[ n ] <<= e;
1348 catch ( beans::PropertyVetoException const & e )
1350 aRet[ n ] <<= e;
1352 catch ( lang::IllegalArgumentException const & e )
1354 aRet[ n ] <<= e;
1357 else
1359 aRet[ n ] <<= uno::Exception(
1360 OUString(
1361 "No property set for storing the value!" ),
1362 static_cast< cppu::OWeakObject * >( this ) );
1367 if ( bExchange )
1369 uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
1371 // Assemble new content identifier...
1372 OUString aNewURL = m_aUri.getParentUri();
1373 aNewURL += "/";
1374 aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle );
1375 uno::Reference< ucb::XContentIdentifier > xNewId
1376 = new ::ucbhelper::ContentIdentifier( aNewURL );
1378 aGuard.clear();
1379 if ( exchangeIdentity( xNewId ) )
1381 // Adapt persistent data.
1382 renameData( xOldId, xNewId );
1384 // Adapt Additional Core Properties.
1385 renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1386 xNewId->getContentIdentifier(),
1387 true );
1389 else
1391 // Do not set new title!
1392 aNewTitle.clear();
1394 // Set error .
1395 aRet[ nTitlePos ] <<= uno::Exception(
1396 OUString("Exchange failed!"),
1397 static_cast< cppu::OWeakObject * >( this ) );
1401 if ( !aNewTitle.isEmpty() )
1403 aEvent.PropertyName = "Title";
1404 aEvent.OldValue = uno::makeAny( m_aProps.aTitle );
1405 aEvent.NewValue = uno::makeAny( aNewTitle );
1407 m_aProps.aTitle = aNewTitle;
1409 aChanges.getArray()[ nChanged ] = aEvent;
1410 nChanged++;
1413 if ( nChanged > 0 )
1415 // Save changes, if content was already made persistent.
1416 if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
1417 ( bStore && ( m_eState == PERSISTENT ) ) )
1419 if ( !storeData( uno::Reference< io::XInputStream >() ) )
1421 uno::Any aProps
1422 = uno::makeAny(
1423 beans::PropertyValue(
1424 OUString(
1425 "Uri"),
1427 uno::makeAny(m_xIdentifier->
1428 getContentIdentifier()),
1429 beans::PropertyState_DIRECT_VALUE));
1430 ucbhelper::cancelCommandExecution(
1431 ucb::IOErrorCode_CANT_WRITE,
1432 uno::Sequence< uno::Any >(&aProps, 1),
1433 xEnv,
1434 OUString(
1435 "Cannot store persistent data!" ),
1436 this );
1437 // Unreachable
1441 aGuard.clear();
1442 aChanges.realloc( nChanged );
1443 notifyPropertiesChange( aChanges );
1446 return aRet;
1450 uno::Any Content::open(
1451 const ucb::OpenCommandArgument2& rArg,
1452 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1453 throw( uno::Exception )
1455 if ( rArg.Mode == ucb::OpenMode::ALL ||
1456 rArg.Mode == ucb::OpenMode::FOLDERS ||
1457 rArg.Mode == ucb::OpenMode::DOCUMENTS )
1460 // open command for a folder content
1463 uno::Reference< ucb::XDynamicResultSet > xSet
1464 = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1465 return uno::makeAny( xSet );
1467 else
1470 // open command for a document content
1473 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1474 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1476 // Currently(?) unsupported.
1477 ucbhelper::cancelCommandExecution(
1478 uno::makeAny( ucb::UnsupportedOpenModeException(
1479 OUString(),
1480 static_cast< cppu::OWeakObject * >( this ),
1481 sal_Int16( rArg.Mode ) ) ),
1482 xEnv );
1483 // Unreachable
1486 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1487 if ( xOut.is() )
1489 // PUSH: write data into xOut
1491 uno::Reference< io::XInputStream > xIn = getInputStream();
1492 if ( !xIn.is() )
1494 // No interaction if we are not persistent!
1495 uno::Any aProps
1496 = uno::makeAny(
1497 beans::PropertyValue(
1498 OUString(
1499 "Uri"),
1501 uno::makeAny(m_xIdentifier->
1502 getContentIdentifier()),
1503 beans::PropertyState_DIRECT_VALUE));
1504 ucbhelper::cancelCommandExecution(
1505 ucb::IOErrorCode_CANT_READ,
1506 uno::Sequence< uno::Any >(&aProps, 1),
1507 m_eState == PERSISTENT
1508 ? xEnv
1509 : uno::Reference< ucb::XCommandEnvironment >(),
1510 OUString("Got no data stream!"),
1511 this );
1512 // Unreachable
1517 uno::Sequence< sal_Int8 > aBuffer;
1518 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1520 while ( nRead > 0 )
1522 aBuffer.realloc( nRead );
1523 xOut->writeBytes( aBuffer );
1524 aBuffer.realloc( 0 );
1525 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1528 xOut->closeOutput();
1530 catch ( io::NotConnectedException const & )
1532 // closeOutput, readSomeBytes, writeBytes
1534 catch ( io::BufferSizeExceededException const & )
1536 // closeOutput, readSomeBytes, writeBytes
1538 catch ( io::IOException const & )
1540 // closeOutput, readSomeBytes, writeBytes
1543 else
1545 uno::Reference< io::XActiveDataSink > xDataSink(
1546 rArg.Sink, uno::UNO_QUERY );
1547 if ( xDataSink.is() )
1549 // PULL: wait for client read
1551 uno::Reference< io::XInputStream > xIn = getInputStream();
1552 if ( !xIn.is() )
1554 // No interaction if we are not persistent!
1555 uno::Any aProps
1556 = uno::makeAny(
1557 beans::PropertyValue(
1558 OUString( "Uri"),
1560 uno::makeAny(m_xIdentifier->
1561 getContentIdentifier()),
1562 beans::PropertyState_DIRECT_VALUE));
1563 ucbhelper::cancelCommandExecution(
1564 ucb::IOErrorCode_CANT_READ,
1565 uno::Sequence< uno::Any >(&aProps, 1),
1566 m_eState == PERSISTENT
1567 ? xEnv
1568 : uno::Reference<
1569 ucb::XCommandEnvironment >(),
1570 OUString( "Got no data stream!" ),
1571 this );
1572 // Unreachable
1575 // Done.
1576 xDataSink->setInputStream( xIn );
1578 else
1580 // Note: aOpenCommand.Sink may contain an XStream
1581 // implementation. Support for this type of
1582 // sink is optional...
1583 ucbhelper::cancelCommandExecution(
1584 uno::makeAny(
1585 ucb::UnsupportedDataSinkException(
1586 OUString(),
1587 static_cast< cppu::OWeakObject * >( this ),
1588 rArg.Sink ) ),
1589 xEnv );
1590 // Unreachable
1595 return uno::Any();
1599 void Content::insert(
1600 const uno::Reference< io::XInputStream >& xStream,
1601 sal_Int32 nNameClashResolve,
1602 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1603 throw( uno::Exception )
1605 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1607 // Check, if all required properties were set.
1608 if ( isFolder() )
1610 // Required: Title
1612 if ( m_aProps.aTitle.isEmpty() )
1613 m_aProps.aTitle = m_aUri.getName();
1615 else
1617 // Required: rArg.Data
1619 if ( !xStream.is() )
1621 ucbhelper::cancelCommandExecution(
1622 uno::makeAny( ucb::MissingInputStreamException(
1623 OUString(),
1624 static_cast< cppu::OWeakObject * >( this ) ) ),
1625 xEnv );
1626 // Unreachable
1629 // Required: Title
1631 if ( m_aProps.aTitle.isEmpty() )
1632 m_aProps.aTitle = m_aUri.getName();
1635 OUString aNewURL = m_aUri.getParentUri();
1636 if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
1637 aNewURL += "/";
1638 aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
1639 PackageUri aNewUri( aNewURL );
1641 // Handle possible name clash...
1642 switch ( nNameClashResolve )
1644 // fail.
1645 case ucb::NameClash::ERROR:
1646 if ( hasData( aNewUri ) )
1648 ucbhelper::cancelCommandExecution(
1649 uno::makeAny( ucb::NameClashException(
1650 OUString(),
1651 static_cast< cppu::OWeakObject * >( this ),
1652 task::InteractionClassification_ERROR,
1653 m_aProps.aTitle ) ),
1654 xEnv );
1655 // Unreachable
1657 break;
1659 // replace (possibly) existing object.
1660 case ucb::NameClash::OVERWRITE:
1661 break;
1663 // "invent" a new valid title.
1664 case ucb::NameClash::RENAME:
1665 if ( hasData( aNewUri ) )
1667 sal_Int32 nTry = 0;
1671 OUString aNew = aNewUri.getUri();
1672 aNew += "_";
1673 aNew += OUString::number( ++nTry );
1674 aNewUri.setUri( aNew );
1676 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1678 if ( nTry == 1000 )
1680 ucbhelper::cancelCommandExecution(
1681 uno::makeAny(
1682 ucb::UnsupportedNameClashException(
1683 OUString( "Unable to resolve name clash!" ),
1684 static_cast< cppu::OWeakObject * >( this ),
1685 nNameClashResolve ) ),
1686 xEnv );
1687 // Unreachable
1689 else
1691 m_aProps.aTitle += "_";
1692 m_aProps.aTitle += OUString::number( nTry );
1695 break;
1697 case ucb::NameClash::KEEP: // deprecated
1698 case ucb::NameClash::ASK:
1699 default:
1700 if ( hasData( aNewUri ) )
1702 ucbhelper::cancelCommandExecution(
1703 uno::makeAny(
1704 ucb::UnsupportedNameClashException(
1705 OUString(),
1706 static_cast< cppu::OWeakObject * >( this ),
1707 nNameClashResolve ) ),
1708 xEnv );
1709 // Unreachable
1711 break;
1714 // Identifier changed?
1715 bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
1717 if ( bNewId )
1719 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1720 m_aUri = aNewUri;
1723 if ( !storeData( xStream ) )
1725 uno::Any aProps
1726 = uno::makeAny(beans::PropertyValue(
1727 OUString( "Uri"),
1729 uno::makeAny(m_xIdentifier->
1730 getContentIdentifier()),
1731 beans::PropertyState_DIRECT_VALUE));
1732 ucbhelper::cancelCommandExecution(
1733 ucb::IOErrorCode_CANT_WRITE,
1734 uno::Sequence< uno::Any >(&aProps, 1),
1735 xEnv,
1736 OUString("Cannot store persistent data!"),
1737 this );
1738 // Unreachable
1741 m_eState = PERSISTENT;
1743 if ( bNewId )
1745 // Take over correct default values from underlying packager...
1746 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1747 loadData( m_pProvider,
1748 m_aUri,
1749 m_aProps,
1750 xXHierarchicalNameAccess );
1752 aGuard.clear();
1753 inserted();
1758 void Content::destroy(
1759 bool bDeletePhysical,
1760 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1761 throw( uno::Exception )
1763 // @@@ take care about bDeletePhysical -> trashcan support
1765 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1767 uno::Reference< ucb::XContent > xThis = this;
1769 // Persistent?
1770 if ( m_eState != PERSISTENT )
1772 ucbhelper::cancelCommandExecution(
1773 uno::makeAny( ucb::UnsupportedCommandException(
1774 OUString( "Not persistent!" ),
1775 static_cast< cppu::OWeakObject * >( this ) ) ),
1776 xEnv );
1777 // Unreachable
1780 m_eState = DEAD;
1782 aGuard.clear();
1783 deleted();
1785 if ( isFolder() )
1787 // Process instantiated children...
1789 ContentRefList aChildren;
1790 queryChildren( aChildren );
1792 ContentRefList::const_iterator it = aChildren.begin();
1793 ContentRefList::const_iterator end = aChildren.end();
1795 while ( it != end )
1797 (*it)->destroy( bDeletePhysical, xEnv );
1798 ++it;
1804 void Content::transfer(
1805 const ucb::TransferInfo& rInfo,
1806 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1807 throw( uno::Exception )
1809 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1811 // Persistent?
1812 if ( m_eState != PERSISTENT )
1814 ucbhelper::cancelCommandExecution(
1815 uno::makeAny( ucb::UnsupportedCommandException(
1816 OUString( "Not persistent!" ),
1817 static_cast< cppu::OWeakObject * >( this ) ) ),
1818 xEnv );
1819 // Unreachable
1822 // Is source a package content?
1823 if ( ( rInfo.SourceURL.isEmpty() ) ||
1824 ( rInfo.SourceURL.compareTo(
1825 m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
1827 ucbhelper::cancelCommandExecution(
1828 uno::makeAny( ucb::InteractiveBadTransferURLException(
1829 OUString(),
1830 static_cast< cppu::OWeakObject * >( this ) ) ),
1831 xEnv );
1832 // Unreachable
1835 // Is source not a parent of me / not me?
1836 OUString aId = m_aUri.getParentUri();
1837 aId += "/";
1839 if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1841 if ( aId.startsWith( rInfo.SourceURL ) )
1843 uno::Any aProps
1844 = uno::makeAny(beans::PropertyValue(
1845 OUString( "Uri"),
1847 uno::makeAny(rInfo.SourceURL),
1848 beans::PropertyState_DIRECT_VALUE));
1849 ucbhelper::cancelCommandExecution(
1850 ucb::IOErrorCode_RECURSIVE,
1851 uno::Sequence< uno::Any >(&aProps, 1),
1852 xEnv,
1853 OUString( "Target is equal to or is a child of source!" ),
1854 this );
1855 // Unreachable
1860 // 0) Obtain content object for source.
1863 uno::Reference< ucb::XContentIdentifier > xId
1864 = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1866 // Note: The static cast is okay here, because its sure that
1867 // m_xProvider is always the PackageContentProvider.
1868 rtl::Reference< Content > xSource;
1872 xSource = static_cast< Content * >(
1873 m_xProvider->queryContent( xId ).get() );
1875 catch ( ucb::IllegalIdentifierException const & )
1877 // queryContent
1880 if ( !xSource.is() )
1882 uno::Any aProps
1883 = uno::makeAny(beans::PropertyValue(
1884 OUString( "Uri"),
1886 uno::makeAny(xId->getContentIdentifier()),
1887 beans::PropertyState_DIRECT_VALUE));
1888 ucbhelper::cancelCommandExecution(
1889 ucb::IOErrorCode_CANT_READ,
1890 uno::Sequence< uno::Any >(&aProps, 1),
1891 xEnv,
1892 OUString( "Cannot instanciate source object!" ),
1893 this );
1894 // Unreachable
1898 // 1) Create new child content.
1901 OUString aType = xSource->isFolder()
1902 ? getContentType( m_aUri.getScheme(), true )
1903 : getContentType( m_aUri.getScheme(), false );
1904 ucb::ContentInfo aContentInfo;
1905 aContentInfo.Type = aType;
1906 aContentInfo.Attributes = 0;
1908 // Note: The static cast is okay here, because its sure that
1909 // createNewContent always creates a Content.
1910 rtl::Reference< Content > xTarget
1911 = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1912 if ( !xTarget.is() )
1914 uno::Any aProps
1915 = uno::makeAny(beans::PropertyValue(
1916 OUString( "Folder"),
1918 uno::makeAny(aId),
1919 beans::PropertyState_DIRECT_VALUE));
1920 ucbhelper::cancelCommandExecution(
1921 ucb::IOErrorCode_CANT_CREATE,
1922 uno::Sequence< uno::Any >(&aProps, 1),
1923 xEnv,
1924 OUString( "XContentCreator::createNewContent failed!" ),
1925 this );
1926 // Unreachable
1930 // 2) Copy data from source content to child content.
1933 uno::Sequence< beans::Property > aSourceProps
1934 = xSource->getPropertySetInfo( xEnv )->getProperties();
1935 sal_Int32 nCount = aSourceProps.getLength();
1937 if ( nCount )
1939 bool bHadTitle = rInfo.NewTitle.isEmpty();
1941 // Get all source values.
1942 uno::Reference< sdbc::XRow > xRow
1943 = xSource->getPropertyValues( aSourceProps );
1945 uno::Sequence< beans::PropertyValue > aValues( nCount );
1946 beans::PropertyValue* pValues = aValues.getArray();
1948 const beans::Property* pProps = aSourceProps.getConstArray();
1949 for ( sal_Int32 n = 0; n < nCount; ++n )
1951 const beans::Property& rProp = pProps[ n ];
1952 beans::PropertyValue& rValue = pValues[ n ];
1954 rValue.Name = rProp.Name;
1955 rValue.Handle = rProp.Handle;
1957 if ( !bHadTitle && rProp.Name == "Title" )
1959 // Set new title instead of original.
1960 bHadTitle = true;
1961 rValue.Value <<= rInfo.NewTitle;
1963 else
1964 rValue.Value
1965 = xRow->getObject( n + 1,
1966 uno::Reference<
1967 container::XNameAccess >() );
1969 rValue.State = beans::PropertyState_DIRECT_VALUE;
1971 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1973 // Add Additional Core Property.
1976 xTarget->addProperty( rProp.Name,
1977 rProp.Attributes,
1978 rValue.Value );
1980 catch ( beans::PropertyExistException const & )
1983 catch ( beans::IllegalTypeException const & )
1986 catch ( lang::IllegalArgumentException const & )
1992 // Set target values.
1993 xTarget->setPropertyValues( aValues, xEnv );
1997 // 3) Commit (insert) child.
2000 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
2003 // 4) Transfer (copy) children of source.
2006 if ( xSource->isFolder() )
2008 uno::Reference< container::XEnumeration > xIter
2009 = xSource->getIterator();
2010 if ( xIter.is() )
2012 while ( xIter->hasMoreElements() )
2016 uno::Reference< container::XNamed > xNamed;
2017 xIter->nextElement() >>= xNamed;
2019 if ( !xNamed.is() )
2021 OSL_FAIL( "Content::transfer - Got no XNamed!" );
2022 break;
2025 OUString aName = xNamed->getName();
2027 if ( aName.isEmpty() )
2029 OSL_FAIL( "Content::transfer - Empty name!" );
2030 break;
2033 OUString aChildId = xId->getContentIdentifier();
2034 if ( ( aChildId.lastIndexOf( '/' ) + 1 )
2035 != aChildId.getLength() )
2036 aChildId += "/";
2038 aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
2040 ucb::TransferInfo aInfo;
2041 aInfo.MoveData = sal_False;
2042 aInfo.NewTitle.clear();
2043 aInfo.SourceURL = aChildId;
2044 aInfo.NameClash = rInfo.NameClash;
2046 // Transfer child to target.
2047 xTarget->transfer( aInfo, xEnv );
2049 catch ( container::NoSuchElementException const & )
2052 catch ( lang::WrappedTargetException const & )
2060 // 5) Destroy source ( when moving only ) .
2063 if ( rInfo.MoveData )
2065 xSource->destroy( true, xEnv );
2067 // Remove all persistent data of source and its children.
2068 if ( !xSource->removeData() )
2070 uno::Any aProps
2071 = uno::makeAny(
2072 beans::PropertyValue(
2073 OUString( "Uri"),
2075 uno::makeAny(
2076 xSource->m_xIdentifier->
2077 getContentIdentifier()),
2078 beans::PropertyState_DIRECT_VALUE));
2079 ucbhelper::cancelCommandExecution(
2080 ucb::IOErrorCode_CANT_WRITE,
2081 uno::Sequence< uno::Any >(&aProps, 1),
2082 xEnv,
2083 OUString( "Cannot remove persistent data of source object!" ),
2084 this );
2085 // Unreachable
2088 // Remove own and all children's Additional Core Properties.
2089 xSource->removeAdditionalPropertySet( true );
2094 bool Content::exchangeIdentity(
2095 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2097 if ( !xNewId.is() )
2098 return false;
2100 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2102 uno::Reference< ucb::XContent > xThis = this;
2104 // Already persistent?
2105 if ( m_eState != PERSISTENT )
2107 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2108 return false;
2111 // Exchange own identitity.
2113 // Fail, if a content with given id already exists.
2114 PackageUri aNewUri( xNewId->getContentIdentifier() );
2115 if ( !hasData( aNewUri ) )
2117 OUString aOldURL = m_xIdentifier->getContentIdentifier();
2119 aGuard.clear();
2120 if ( exchange( xNewId ) )
2122 m_aUri = aNewUri;
2123 if ( isFolder() )
2125 // Process instantiated children...
2127 ContentRefList aChildren;
2128 queryChildren( aChildren );
2130 ContentRefList::const_iterator it = aChildren.begin();
2131 ContentRefList::const_iterator end = aChildren.end();
2133 while ( it != end )
2135 ContentRef xChild = (*it);
2137 // Create new content identifier for the child...
2138 uno::Reference< ucb::XContentIdentifier > xOldChildId
2139 = xChild->getIdentifier();
2140 OUString aOldChildURL
2141 = xOldChildId->getContentIdentifier();
2142 OUString aNewChildURL
2143 = aOldChildURL.replaceAt(
2145 aOldURL.getLength(),
2146 xNewId->getContentIdentifier() );
2147 uno::Reference< ucb::XContentIdentifier > xNewChildId
2148 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2150 if ( !xChild->exchangeIdentity( xNewChildId ) )
2151 return false;
2153 ++it;
2156 return true;
2160 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2161 return false;
2165 void Content::queryChildren( ContentRefList& rChildren )
2167 // Obtain a list with a snapshot of all currently instantiated contents
2168 // from provider and extract the contents which are direct children
2169 // of this content.
2171 ::ucbhelper::ContentRefList aAllContents;
2172 m_xProvider->queryExistingContents( aAllContents );
2174 OUString aURL = m_xIdentifier->getContentIdentifier();
2176 OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2177 "Content::queryChildren - Invalid URL!" );
2179 aURL += "/";
2181 sal_Int32 nLen = aURL.getLength();
2183 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2184 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2186 while ( it != end )
2188 ::ucbhelper::ContentImplHelperRef xChild = (*it);
2189 OUString aChildURL
2190 = xChild->getIdentifier()->getContentIdentifier();
2192 // Is aURL a prefix of aChildURL?
2193 if ( ( aChildURL.getLength() > nLen ) &&
2194 ( aChildURL.startsWith( aURL ) ) )
2196 if ( aChildURL.indexOf( '/', nLen ) == -1 )
2198 // No further slashes. It's a child!
2199 rChildren.push_back(
2200 ContentRef(
2201 static_cast< Content * >( xChild.get() ) ) );
2204 ++it;
2209 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2210 const PackageUri& rURI )
2212 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2214 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2215 if ( rURI.getPackage() == m_aUri.getPackage() )
2217 if ( !m_xPackage.is() )
2218 m_xPackage = m_pProvider->createPackage( m_aUri );
2220 return m_xPackage;
2223 return m_pProvider->createPackage( rURI );
2227 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2229 return getPackage( m_aUri );
2233 // static
2234 bool Content::hasData(
2235 ContentProvider* pProvider,
2236 const PackageUri& rURI,
2237 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2239 rxPackage = pProvider->createPackage( rURI );
2240 return rxPackage->hasByHierarchicalName( rURI.getPath() );
2244 bool Content::hasData( const PackageUri& rURI )
2246 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2248 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2249 if ( rURI.getPackage() == m_aUri.getPackage() )
2251 xPackage = getPackage();
2252 return xPackage->hasByHierarchicalName( rURI.getPath() );
2255 return hasData( m_pProvider, rURI, xPackage );
2259 //static
2260 bool Content::loadData(
2261 ContentProvider* pProvider,
2262 const PackageUri& rURI,
2263 ContentProperties& rProps,
2264 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2266 rxPackage = pProvider->createPackage( rURI );
2268 if ( rURI.isRootFolder() )
2270 // Properties available only from package
2271 uno::Reference< beans::XPropertySet > xPackagePropSet(
2272 rxPackage, uno::UNO_QUERY );
2274 OSL_ENSURE( xPackagePropSet.is(),
2275 "Content::loadData - "
2276 "Got no XPropertySet interface from package!" );
2278 if ( xPackagePropSet.is() )
2280 // HasEncryptedEntries ( only avalibale at root folder )
2283 uno::Any aHasEncryptedEntries
2284 = xPackagePropSet->getPropertyValue(
2285 OUString( "HasEncryptedEntries" ) );
2286 if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2288 OSL_FAIL( "Content::loadData - "
2289 "Got no HasEncryptedEntries value!" );
2290 return false;
2293 catch ( beans::UnknownPropertyException const & )
2295 OSL_FAIL( "Content::loadData - "
2296 "Got no HasEncryptedEntries value!" );
2297 return false;
2299 catch ( lang::WrappedTargetException const & )
2301 OSL_FAIL( "Content::loadData - "
2302 "Got no HasEncryptedEntries value!" );
2303 return false;
2308 if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2309 return false;
2313 uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2314 if ( aEntry.hasValue() )
2316 uno::Reference< beans::XPropertySet > xPropSet;
2317 aEntry >>= xPropSet;
2319 if ( !xPropSet.is() )
2321 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2322 return false;
2325 // Title
2326 rProps.aTitle = rURI.getName();
2328 // MediaType
2331 uno::Any aMediaType
2332 = xPropSet->getPropertyValue(
2333 OUString("MediaType") );
2334 if ( !( aMediaType >>= rProps.aMediaType ) )
2336 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2337 return false;
2340 catch ( beans::UnknownPropertyException const & )
2342 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2343 return false;
2345 catch ( lang::WrappedTargetException const & )
2347 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2348 return false;
2351 uno::Reference< container::XEnumerationAccess > xEnumAccess;
2352 aEntry >>= xEnumAccess;
2354 // ContentType / IsFolder / IsDocument
2355 if ( xEnumAccess.is() )
2357 // folder
2358 rProps.aContentType = getContentType( rURI.getScheme(), true );
2359 rProps.bIsDocument = false;
2360 rProps.bIsFolder = true;
2362 else
2364 // stream
2365 rProps.aContentType = getContentType( rURI.getScheme(), false );
2366 rProps.bIsDocument = true;
2367 rProps.bIsFolder = false;
2370 if ( rProps.bIsDocument )
2372 // Size ( only available for streams )
2375 uno::Any aSize
2376 = xPropSet->getPropertyValue(
2377 OUString("Size") );
2378 if ( !( aSize >>= rProps.nSize ) )
2380 OSL_FAIL( "Content::loadData - Got no Size value!" );
2381 return false;
2384 catch ( beans::UnknownPropertyException const & )
2386 OSL_FAIL( "Content::loadData - Got no Size value!" );
2387 return false;
2389 catch ( lang::WrappedTargetException const & )
2391 OSL_FAIL( "Content::loadData - Got no Size value!" );
2392 return false;
2395 // Compressed ( only available for streams )
2398 uno::Any aCompressed
2399 = xPropSet->getPropertyValue(
2400 OUString("Compressed") );
2401 if ( !( aCompressed >>= rProps.bCompressed ) )
2403 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2404 return false;
2407 catch ( beans::UnknownPropertyException const & )
2409 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2410 return false;
2412 catch ( lang::WrappedTargetException const & )
2414 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2415 return false;
2418 // Encrypted ( only available for streams )
2421 uno::Any aEncrypted
2422 = xPropSet->getPropertyValue(
2423 OUString("Encrypted") );
2424 if ( !( aEncrypted >>= rProps.bEncrypted ) )
2426 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2427 return false;
2430 catch ( beans::UnknownPropertyException const & )
2432 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2433 return false;
2435 catch ( lang::WrappedTargetException const & )
2437 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2438 return false;
2441 return true;
2444 catch ( container::NoSuchElementException const & )
2446 // getByHierarchicalName
2449 return false;
2453 bool Content::renameData(
2454 const uno::Reference< ucb::XContentIdentifier >& xOldId,
2455 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2457 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2459 PackageUri aURI( xOldId->getContentIdentifier() );
2460 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2461 aURI );
2463 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2464 return false;
2468 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2469 uno::Reference< container::XNamed > xNamed;
2470 aEntry >>= xNamed;
2472 if ( !xNamed.is() )
2474 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2475 return false;
2478 PackageUri aNewURI( xNewId->getContentIdentifier() );
2480 // No success indicator!? No return value / exceptions specified.
2481 xNamed->setName( aNewURI.getName() );
2483 return true;
2485 catch ( container::NoSuchElementException const & )
2487 // getByHierarchicalName
2490 return false;
2494 bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2496 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2498 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2500 uno::Reference< beans::XPropertySet > xPackagePropSet(
2501 xNA, uno::UNO_QUERY );
2502 OSL_ENSURE( xPackagePropSet.is(),
2503 "Content::storeData - "
2504 "Got no XPropertySet interface from package!" );
2506 if ( !xPackagePropSet.is() )
2507 return false;
2509 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2511 if ( m_aUri.isRootFolder() )
2513 // Property available only from package and from streams (see below)
2516 xPackagePropSet->setPropertyValue(
2517 OUString("EncryptionKey"),
2518 uno::makeAny( m_aProps.aEncryptionKey ) );
2519 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2521 catch ( beans::UnknownPropertyException const & )
2523 // setPropertyValue
2525 catch ( beans::PropertyVetoException const & )
2527 // setPropertyValue
2529 catch ( lang::IllegalArgumentException const & )
2531 // setPropertyValue
2533 catch ( lang::WrappedTargetException const & )
2535 // setPropertyValue
2540 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2542 // if ( !bCreate )
2543 // return sal_True;
2547 // Create new resource...
2548 uno::Reference< lang::XSingleServiceFactory > xFac(
2549 xNA, uno::UNO_QUERY );
2550 if ( !xFac.is() )
2552 OSL_FAIL( "Content::storeData - "
2553 "Got no XSingleServiceFactory interface!" );
2554 return false;
2557 uno::Sequence< uno::Any > aArgs( 1 );
2558 aArgs[ 0 ] <<= isFolder();
2560 uno::Reference< uno::XInterface > xNew
2561 = xFac->createInstanceWithArguments( aArgs );
2563 if ( !xNew.is() )
2565 OSL_FAIL( "Content::storeData - createInstance failed!" );
2566 return false;
2569 PackageUri aParentUri( getParentURL() );
2570 uno::Any aEntry
2571 = xNA->getByHierarchicalName( aParentUri.getPath() );
2572 uno::Reference< container::XNameContainer > xParentContainer;
2573 aEntry >>= xParentContainer;
2575 if ( !xParentContainer.is() )
2577 OSL_FAIL( "Content::storeData - "
2578 "Got no XNameContainer interface!" );
2579 return false;
2582 xParentContainer->insertByName( m_aProps.aTitle,
2583 uno::makeAny( xNew ) );
2585 catch ( lang::IllegalArgumentException const & )
2587 // insertByName
2588 OSL_FAIL( "Content::storeData - insertByName failed!" );
2589 return false;
2591 catch ( uno::RuntimeException const & )
2593 throw;
2595 catch ( container::ElementExistException const & )
2597 // insertByName
2598 OSL_FAIL( "Content::storeData - insertByName failed!" );
2599 return false;
2601 catch ( lang::WrappedTargetException const & )
2603 // insertByName
2604 OSL_FAIL( "Content::storeData - insertByName failed!" );
2605 return false;
2607 catch ( container::NoSuchElementException const & )
2609 // getByHierarchicalName
2610 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2611 return false;
2613 catch ( uno::Exception const & )
2615 // createInstanceWithArguments
2616 OSL_FAIL( "Content::storeData - Error!" );
2617 return false;
2621 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2622 return false;
2626 uno::Reference< beans::XPropertySet > xPropSet;
2627 xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2629 if ( !xPropSet.is() )
2631 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2632 return false;
2636 // Store property values...
2639 if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2641 xPropSet->setPropertyValue(
2642 OUString("MediaType"),
2643 uno::makeAny( m_aProps.aMediaType ) );
2644 m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2647 if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2649 if ( !isFolder() )
2650 xPropSet->setPropertyValue(
2651 OUString("Compressed"),
2652 uno::makeAny( m_aProps.bCompressed ) );
2654 m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2657 if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2659 if ( !isFolder() )
2660 xPropSet->setPropertyValue(
2661 OUString("Encrypted"),
2662 uno::makeAny( m_aProps.bEncrypted ) );
2664 m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2667 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2669 if ( !isFolder() )
2670 xPropSet->setPropertyValue(
2671 OUString("EncryptionKey"),
2672 uno::makeAny( m_aProps.aEncryptionKey ) );
2674 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2678 // Store data stream...
2681 if ( xStream.is() && !isFolder() )
2683 uno::Reference< io::XActiveDataSink > xSink(
2684 xPropSet, uno::UNO_QUERY );
2686 if ( !xSink.is() )
2688 OSL_FAIL( "Content::storeData - "
2689 "Got no XActiveDataSink interface!" );
2690 return false;
2693 xSink->setInputStream( xStream );
2696 return true;
2698 catch ( container::NoSuchElementException const & )
2700 // getByHierarchicalName
2702 catch ( beans::UnknownPropertyException const & )
2704 // setPropertyValue
2706 catch ( beans::PropertyVetoException const & )
2708 // setPropertyValue
2710 catch ( lang::IllegalArgumentException const & )
2712 // setPropertyValue
2714 catch ( lang::WrappedTargetException const & )
2716 // setPropertyValue
2719 OSL_FAIL( "Content::storeData - Error!" );
2720 return false;
2724 bool Content::removeData()
2726 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2728 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2730 PackageUri aParentUri( getParentURL() );
2731 if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2732 return false;
2736 uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2737 uno::Reference< container::XNameContainer > xContainer;
2738 aEntry >>= xContainer;
2740 if ( !xContainer.is() )
2742 OSL_FAIL( "Content::removeData - "
2743 "Got no XNameContainer interface!" );
2744 return false;
2747 xContainer->removeByName( m_aUri.getName() );
2748 return true;
2750 catch ( container::NoSuchElementException const & )
2752 // getByHierarchicalName, removeByName
2754 catch ( lang::WrappedTargetException const & )
2756 // removeByName
2759 OSL_FAIL( "Content::removeData - Error!" );
2760 return false;
2764 bool Content::flushData()
2766 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2768 // Note: XChangesBatch is only implemented by the package itself, not
2769 // by the single entries. Maybe this has to change...
2771 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2773 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2774 if ( !xBatch.is() )
2776 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2777 return false;
2782 xBatch->commitChanges();
2783 return true;
2785 catch ( lang::WrappedTargetException const & )
2789 OSL_FAIL( "Content::flushData - Error!" );
2790 return false;
2794 uno::Reference< io::XInputStream > Content::getInputStream()
2796 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2798 uno::Reference< io::XInputStream > xStream;
2799 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2801 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2802 return xStream;
2806 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2807 uno::Reference< io::XActiveDataSink > xSink;
2808 aEntry >>= xSink;
2810 if ( !xSink.is() )
2812 OSL_FAIL( "Content::getInputStream - "
2813 "Got no XActiveDataSink interface!" );
2814 return xStream;
2817 xStream = xSink->getInputStream();
2819 OSL_ENSURE( xStream.is(),
2820 "Content::getInputStream - Got no stream!" );
2822 catch ( container::NoSuchElementException const & )
2824 // getByHierarchicalName
2827 return xStream;
2831 uno::Reference< container::XEnumeration > Content::getIterator()
2833 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2835 uno::Reference< container::XEnumeration > xIter;
2836 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2838 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2839 return xIter;
2843 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2844 uno::Reference< container::XEnumerationAccess > xIterFac;
2845 aEntry >>= xIterFac;
2847 if ( !xIterFac.is() )
2849 OSL_FAIL( "Content::getIterator - "
2850 "Got no XEnumerationAccess interface!" );
2851 return xIter;
2854 xIter = xIterFac->createEnumeration();
2856 OSL_ENSURE( xIter.is(),
2857 "Content::getIterator - Got no iterator!" );
2859 catch ( container::NoSuchElementException const & )
2861 // getByHierarchicalName
2864 return xIter;
2867 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */