Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / ucp / package / pkgcontent.cxx
blob19f2017716bb88f0aa280223d0bc2bc8c413c27c
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 <rtl/ustring.hxx>
28 #include <com/sun/star/beans/IllegalTypeException.hpp>
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 #include <com/sun/star/beans/PropertyExistException.hpp>
31 #include <com/sun/star/beans/PropertyState.hpp>
32 #include <com/sun/star/container/XEnumerationAccess.hpp>
33 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/container/XNamed.hpp>
36 #include <com/sun/star/io/BufferSizeExceededException.hpp>
37 #include <com/sun/star/io/NotConnectedException.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/io/XOutputStream.hpp>
40 #include <com/sun/star/lang/IllegalAccessException.hpp>
41 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
42 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
43 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
44 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
45 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
46 #include <com/sun/star/ucb/NameClash.hpp>
47 #include <com/sun/star/ucb/NameClashException.hpp>
48 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
49 #include <com/sun/star/ucb/OpenMode.hpp>
50 #include <com/sun/star/ucb/TransferInfo.hpp>
51 #include <com/sun/star/ucb/UnsupportedCommandException.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/lang/XSingleServiceFactory.hpp>
59 #include <com/sun/star/uno/Any.hxx>
60 #include <com/sun/star/uno/Sequence.hxx>
61 #include <comphelper/propertysequence.hxx>
62 #include <cppuhelper/queryinterface.hxx>
63 #include <ucbhelper/contentidentifier.hxx>
64 #include <ucbhelper/propertyvalueset.hxx>
65 #include <ucbhelper/cancelcommandexecution.hxx>
66 #include <ucbhelper/macros.hxx>
67 #include "pkgcontent.hxx"
68 #include "pkgprovider.hxx"
69 #include "pkgresultset.hxx"
71 #include "../inc/urihelper.hxx"
73 using namespace com::sun::star;
74 using namespace package_ucp;
76 #define NONE_MODIFIED sal_uInt32( 0x00 )
77 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
78 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
79 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
80 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
83 // ContentProperties Implementation.
86 ContentProperties::ContentProperties( const OUString& rContentType )
87 : aContentType( rContentType ),
88 nSize( 0 ),
89 bCompressed( true ),
90 bEncrypted( false ),
91 bHasEncryptedEntries( false )
93 bIsFolder = rContentType == PACKAGE_FOLDER_CONTENT_TYPE || rContentType == PACKAGE_ZIP_FOLDER_CONTENT_TYPE;
94 bIsDocument = !bIsFolder;
96 OSL_ENSURE( bIsFolder || rContentType == PACKAGE_STREAM_CONTENT_TYPE || rContentType == PACKAGE_ZIP_STREAM_CONTENT_TYPE,
97 "ContentProperties::ContentProperties - Unknown type!" );
101 uno::Sequence< ucb::ContentInfo >
102 ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
104 if ( bIsFolder )
106 uno::Sequence< beans::Property > aProps( 1 );
107 aProps.getArray()[ 0 ] = beans::Property(
108 "Title",
110 cppu::UnoType<OUString>::get(),
111 beans::PropertyAttribute::BOUND );
113 uno::Sequence< ucb::ContentInfo > aSeq( 2 );
115 // Folder.
116 aSeq.getArray()[ 0 ].Type
117 = Content::getContentType( rUri.getScheme(), true );
118 aSeq.getArray()[ 0 ].Attributes
119 = ucb::ContentInfoAttribute::KIND_FOLDER;
120 aSeq.getArray()[ 0 ].Properties = aProps;
122 // Stream.
123 aSeq.getArray()[ 1 ].Type
124 = Content::getContentType( rUri.getScheme(), false );
125 aSeq.getArray()[ 1 ].Attributes
126 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
127 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
128 aSeq.getArray()[ 1 ].Properties = aProps;
130 return aSeq;
132 else
134 return uno::Sequence< ucb::ContentInfo >( 0 );
139 // Content Implementation.
142 // static ( "virtual" ctor )
143 Content* Content::create(
144 const uno::Reference< uno::XComponentContext >& rxContext,
145 ContentProvider* pProvider,
146 const uno::Reference< ucb::XContentIdentifier >& Identifier )
148 OUString aURL = Identifier->getContentIdentifier();
149 PackageUri aURI( aURL );
150 ContentProperties aProps;
151 uno::Reference< container::XHierarchicalNameAccess > xPackage;
153 if ( loadData( pProvider, aURI, aProps, xPackage ) )
155 // resource exists
157 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
158 if ( ( nLastSlash + 1 ) == aURL.getLength() )
160 // Client explicitly requested a folder!
161 if ( !aProps.bIsFolder )
162 return nullptr;
165 uno::Reference< ucb::XContentIdentifier > xId
166 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
167 return new Content( rxContext, pProvider, xId, xPackage, aURI, aProps );
169 else
171 // resource doesn't exist
173 bool bFolder = false;
175 // Guess type according to URI.
176 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
177 if ( ( nLastSlash + 1 ) == aURL.getLength() )
178 bFolder = true;
180 uno::Reference< ucb::XContentIdentifier > xId
181 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
183 ucb::ContentInfo aInfo;
184 if ( bFolder || aURI.isRootFolder() )
185 aInfo.Type = getContentType( aURI.getScheme(), true );
186 else
187 aInfo.Type = getContentType( aURI.getScheme(), false );
189 return new Content( rxContext, pProvider, xId, xPackage, aURI, aInfo );
194 // static ( "virtual" ctor )
195 Content* Content::create(
196 const uno::Reference< uno::XComponentContext >& rxContext,
197 ContentProvider* pProvider,
198 const uno::Reference< ucb::XContentIdentifier >& Identifier,
199 const ucb::ContentInfo& Info )
201 if ( Info.Type.isEmpty() )
202 return nullptr;
204 PackageUri aURI( Identifier->getContentIdentifier() );
206 if ( !Info.Type.equalsIgnoreAsciiCase(
207 getContentType( aURI.getScheme(), true ) ) &&
208 !Info.Type.equalsIgnoreAsciiCase(
209 getContentType( aURI.getScheme(), false ) ) )
210 return nullptr;
212 uno::Reference< container::XHierarchicalNameAccess > xPackage = pProvider->createPackage( aURI );
214 uno::Reference< ucb::XContentIdentifier > xId
215 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
216 return new Content( rxContext, pProvider, xId, xPackage, aURI, Info );
220 // static
221 OUString Content::getContentType(
222 const OUString& aScheme, bool bFolder )
224 return ( "application/"
225 + aScheme
226 + ( bFolder
227 ? OUStringLiteral("-folder")
228 : OUStringLiteral("-stream") ) );
232 Content::Content(
233 const uno::Reference< uno::XComponentContext >& rxContext,
234 ContentProvider* pProvider,
235 const uno::Reference< ucb::XContentIdentifier >& Identifier,
236 const uno::Reference< container::XHierarchicalNameAccess > & Package,
237 const PackageUri& rUri,
238 const ContentProperties& rProps )
239 : ContentImplHelper( rxContext, pProvider, Identifier ),
240 m_aUri( rUri ),
241 m_aProps( rProps ),
242 m_eState( PERSISTENT ),
243 m_xPackage( Package ),
244 m_pProvider( pProvider ),
245 m_nModifiedProps( NONE_MODIFIED )
250 Content::Content(
251 const uno::Reference< uno::XComponentContext >& rxContext,
252 ContentProvider* pProvider,
253 const uno::Reference< ucb::XContentIdentifier >& Identifier,
254 const uno::Reference< container::XHierarchicalNameAccess > & Package,
255 const PackageUri& rUri,
256 const ucb::ContentInfo& Info )
257 : ContentImplHelper( rxContext, pProvider, Identifier ),
258 m_aUri( rUri ),
259 m_aProps( Info.Type ),
260 m_eState( TRANSIENT ),
261 m_xPackage( Package ),
262 m_pProvider( pProvider ),
263 m_nModifiedProps( NONE_MODIFIED )
268 // virtual
269 Content::~Content()
274 // XInterface methods.
277 // virtual
278 void SAL_CALL Content::acquire()
279 throw( )
281 ContentImplHelper::acquire();
285 // virtual
286 void SAL_CALL Content::release()
287 throw( )
289 ContentImplHelper::release();
293 // virtual
294 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
296 uno::Any aRet;
298 if ( isFolder() )
299 aRet = cppu::queryInterface(
300 rType, static_cast< ucb::XContentCreator * >( this ) );
302 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
306 // XTypeProvider methods.
309 XTYPEPROVIDER_COMMON_IMPL( Content );
312 // virtual
313 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
315 if ( isFolder() )
317 static cppu::OTypeCollection s_aFolderTypes(
318 CPPU_TYPE_REF( lang::XTypeProvider ),
319 CPPU_TYPE_REF( lang::XServiceInfo ),
320 CPPU_TYPE_REF( lang::XComponent ),
321 CPPU_TYPE_REF( ucb::XContent ),
322 CPPU_TYPE_REF( ucb::XCommandProcessor ),
323 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
324 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
325 CPPU_TYPE_REF( beans::XPropertyContainer ),
326 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
327 CPPU_TYPE_REF( container::XChild ),
328 CPPU_TYPE_REF( ucb::XContentCreator ) );
330 return s_aFolderTypes.getTypes();
333 else
335 static cppu::OTypeCollection s_aDocumentTypes(
336 CPPU_TYPE_REF( lang::XTypeProvider ),
337 CPPU_TYPE_REF( lang::XServiceInfo ),
338 CPPU_TYPE_REF( lang::XComponent ),
339 CPPU_TYPE_REF( ucb::XContent ),
340 CPPU_TYPE_REF( ucb::XCommandProcessor ),
341 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
342 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
343 CPPU_TYPE_REF( beans::XPropertyContainer ),
344 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
345 CPPU_TYPE_REF( container::XChild ) );
347 return s_aDocumentTypes.getTypes();
352 // XServiceInfo methods.
355 // virtual
356 OUString SAL_CALL Content::getImplementationName()
358 return "com.sun.star.comp.ucb.PackageContent";
362 // virtual
363 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
365 return { isFolder()? OUString("com.sun.star.ucb.PackageFolderContent"):OUString("com.sun.star.ucb.PackageStreamContent") } ;
369 // XContent methods.
372 // virtual
373 OUString SAL_CALL Content::getContentType()
375 return m_aProps.aContentType;
379 // XCommandProcessor methods.
382 // virtual
383 uno::Any SAL_CALL Content::execute(
384 const ucb::Command& aCommand,
385 sal_Int32 /*CommandId*/,
386 const uno::Reference< ucb::XCommandEnvironment >& Environment )
388 uno::Any aRet;
390 if ( aCommand.Name == "getPropertyValues" )
393 // getPropertyValues
396 uno::Sequence< beans::Property > Properties;
397 if ( !( aCommand.Argument >>= Properties ) )
399 ucbhelper::cancelCommandExecution(
400 uno::makeAny( lang::IllegalArgumentException(
401 "Wrong argument type!",
402 static_cast< cppu::OWeakObject * >( this ),
403 -1 ) ),
404 Environment );
405 // Unreachable
408 aRet <<= getPropertyValues( Properties );
410 else if ( aCommand.Name == "setPropertyValues" )
413 // setPropertyValues
416 uno::Sequence< beans::PropertyValue > aProperties;
417 if ( !( aCommand.Argument >>= aProperties ) )
419 ucbhelper::cancelCommandExecution(
420 uno::makeAny( lang::IllegalArgumentException(
421 "Wrong argument type!",
422 static_cast< cppu::OWeakObject * >( this ),
423 -1 ) ),
424 Environment );
425 // Unreachable
428 if ( !aProperties.hasElements() )
430 ucbhelper::cancelCommandExecution(
431 uno::makeAny( lang::IllegalArgumentException(
432 "No properties!",
433 static_cast< cppu::OWeakObject * >( this ),
434 -1 ) ),
435 Environment );
436 // Unreachable
439 aRet <<= setPropertyValues( aProperties, Environment );
441 else if ( aCommand.Name == "getPropertySetInfo" )
444 // getPropertySetInfo
447 // Note: Implemented by base class.
448 aRet <<= getPropertySetInfo( Environment );
450 else if ( aCommand.Name == "getCommandInfo" )
453 // getCommandInfo
456 // Note: Implemented by base class.
457 aRet <<= getCommandInfo( Environment );
459 else if ( aCommand.Name == "open" )
462 // open
465 ucb::OpenCommandArgument2 aOpenCommand;
466 if ( !( aCommand.Argument >>= aOpenCommand ) )
468 ucbhelper::cancelCommandExecution(
469 uno::makeAny( lang::IllegalArgumentException(
470 "Wrong argument type!",
471 static_cast< cppu::OWeakObject * >( this ),
472 -1 ) ),
473 Environment );
474 // Unreachable
477 aRet = open( aOpenCommand, Environment );
479 else if ( !m_aUri.isRootFolder() && aCommand.Name == "insert" )
482 // insert
485 ucb::InsertCommandArgument aArg;
486 if ( !( aCommand.Argument >>= aArg ) )
488 ucbhelper::cancelCommandExecution(
489 uno::makeAny( lang::IllegalArgumentException(
490 "Wrong argument type!",
491 static_cast< cppu::OWeakObject * >( this ),
492 -1 ) ),
493 Environment );
494 // Unreachable
497 sal_Int32 nNameClash = aArg.ReplaceExisting
498 ? ucb::NameClash::OVERWRITE
499 : ucb::NameClash::ERROR;
500 insert( aArg.Data, nNameClash, Environment );
502 else if ( !m_aUri.isRootFolder() && aCommand.Name == "delete" )
505 // delete
508 bool bDeletePhysical = false;
509 aCommand.Argument >>= bDeletePhysical;
510 destroy( bDeletePhysical, Environment );
512 // Remove own and all children's persistent data.
513 if ( !removeData() )
515 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
517 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
518 }));
519 ucbhelper::cancelCommandExecution(
520 ucb::IOErrorCode_CANT_WRITE,
521 aArgs,
522 Environment,
523 "Cannot remove persistent data!",
524 this );
525 // Unreachable
528 // Remove own and all children's Additional Core Properties.
529 removeAdditionalPropertySet();
531 else if ( aCommand.Name == "transfer" )
534 // transfer
535 // ( Not available at stream objects )
538 ucb::TransferInfo aInfo;
539 if ( !( aCommand.Argument >>= aInfo ) )
541 ucbhelper::cancelCommandExecution(
542 uno::makeAny( lang::IllegalArgumentException(
543 "Wrong argument type!",
544 static_cast< cppu::OWeakObject * >( this ),
545 -1 ) ),
546 Environment );
547 // Unreachable
550 transfer( aInfo, Environment );
552 else if ( aCommand.Name == "createNewContent" && isFolder() )
555 // createNewContent
556 // ( Not available at stream objects )
559 ucb::ContentInfo aInfo;
560 if ( !( aCommand.Argument >>= aInfo ) )
562 OSL_FAIL( "Wrong argument type!" );
563 ucbhelper::cancelCommandExecution(
564 uno::makeAny( lang::IllegalArgumentException(
565 "Wrong argument type!",
566 static_cast< cppu::OWeakObject * >( this ),
567 -1 ) ),
568 Environment );
569 // Unreachable
572 aRet <<= createNewContent( aInfo );
574 else if ( aCommand.Name == "flush" )
577 // flush
578 // ( Not available at stream objects )
581 if( !flushData() )
583 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
585 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
586 }));
587 ucbhelper::cancelCommandExecution(
588 ucb::IOErrorCode_CANT_WRITE,
589 aArgs,
590 Environment,
591 "Cannot write file to disk!",
592 this );
593 // Unreachable
596 else
599 // Unsupported command
602 ucbhelper::cancelCommandExecution(
603 uno::makeAny( ucb::UnsupportedCommandException(
604 OUString(),
605 static_cast< cppu::OWeakObject * >( this ) ) ),
606 Environment );
607 // Unreachable
610 return aRet;
614 // virtual
615 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
617 // @@@ Implement logic to abort running commands, if this makes
618 // sense for your content.
622 // XContentCreator methods.
625 // virtual
626 uno::Sequence< ucb::ContentInfo > SAL_CALL
627 Content::queryCreatableContentsInfo()
629 return m_aProps.getCreatableContentsInfo( m_aUri );
633 // virtual
634 uno::Reference< ucb::XContent > SAL_CALL
635 Content::createNewContent( const ucb::ContentInfo& Info )
637 if ( isFolder() )
639 osl::Guard< osl::Mutex > aGuard( m_aMutex );
641 if ( Info.Type.isEmpty() )
642 return uno::Reference< ucb::XContent >();
644 if ( !Info.Type.equalsIgnoreAsciiCase(
645 getContentType( m_aUri.getScheme(), true ) ) &&
646 !Info.Type.equalsIgnoreAsciiCase(
647 getContentType( m_aUri.getScheme(), false ) ) )
648 return uno::Reference< ucb::XContent >();
650 OUString aURL = m_aUri.getUri() + "/";
652 if ( Info.Type.equalsIgnoreAsciiCase(
653 getContentType( m_aUri.getScheme(), true ) ) )
654 aURL += "New_Folder";
655 else
656 aURL += "New_Stream";
658 uno::Reference< ucb::XContentIdentifier > xId(
659 new ::ucbhelper::ContentIdentifier( aURL ) );
661 return create( m_xContext, m_pProvider, xId, Info );
663 else
665 OSL_FAIL( "createNewContent called on non-folder object!" );
666 return uno::Reference< ucb::XContent >();
671 // Non-interface methods.
674 // virtual
675 OUString Content::getParentURL()
677 return m_aUri.getParentUri();
681 // static
682 uno::Reference< sdbc::XRow > Content::getPropertyValues(
683 const uno::Reference< uno::XComponentContext >& rxContext,
684 const uno::Sequence< beans::Property >& rProperties,
685 ContentProvider* pProvider,
686 const OUString& rContentId )
688 ContentProperties aData;
689 uno::Reference< container::XHierarchicalNameAccess > xPackage;
690 if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) )
692 return getPropertyValues( rxContext,
693 rProperties,
694 aData,
695 rtl::Reference<
696 ::ucbhelper::ContentProviderImplHelper >(
697 pProvider ),
698 rContentId );
700 else
702 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
703 = new ::ucbhelper::PropertyValueSet( rxContext );
705 for ( const beans::Property& rProp : rProperties )
706 xRow->appendVoid( rProp );
708 return uno::Reference< sdbc::XRow >( xRow.get() );
713 // static
714 uno::Reference< sdbc::XRow > Content::getPropertyValues(
715 const uno::Reference< uno::XComponentContext >& rxContext,
716 const uno::Sequence< beans::Property >& rProperties,
717 const ContentProperties& rData,
718 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >&
719 rProvider,
720 const OUString& rContentId )
722 // Note: Empty sequence means "get values of all supported properties".
724 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
725 = new ::ucbhelper::PropertyValueSet( rxContext );
727 if ( rProperties.hasElements() )
729 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
730 bool bTriedToGetAdditionalPropSet = false;
732 for ( const beans::Property& rProp : rProperties )
734 // Process Core properties.
736 if ( rProp.Name == "ContentType" )
738 xRow->appendString ( rProp, rData.aContentType );
740 else if ( rProp.Name == "Title" )
742 xRow->appendString ( rProp, rData.aTitle );
744 else if ( rProp.Name == "IsDocument" )
746 xRow->appendBoolean( rProp, rData.bIsDocument );
748 else if ( rProp.Name == "IsFolder" )
750 xRow->appendBoolean( rProp, rData.bIsFolder );
752 else if ( rProp.Name == "CreatableContentsInfo" )
754 xRow->appendObject(
755 rProp, uno::makeAny(
756 rData.getCreatableContentsInfo(
757 PackageUri( rContentId ) ) ) );
759 else if ( rProp.Name == "MediaType" )
761 xRow->appendString ( rProp, rData.aMediaType );
763 else if ( rProp.Name == "Size" )
765 // Property only available for streams.
766 if ( rData.bIsDocument )
767 xRow->appendLong( rProp, rData.nSize );
768 else
769 xRow->appendVoid( rProp );
771 else if ( rProp.Name == "Compressed" )
773 // Property only available for streams.
774 if ( rData.bIsDocument )
775 xRow->appendBoolean( rProp, rData.bCompressed );
776 else
777 xRow->appendVoid( rProp );
779 else if ( rProp.Name == "Encrypted" )
781 // Property only available for streams.
782 if ( rData.bIsDocument )
783 xRow->appendBoolean( rProp, rData.bEncrypted );
784 else
785 xRow->appendVoid( rProp );
787 else if ( rProp.Name == "HasEncryptedEntries" )
789 // Property only available for root folder.
790 PackageUri aURI( rContentId );
791 if ( aURI.isRootFolder() )
792 xRow->appendBoolean( rProp, rData.bHasEncryptedEntries );
793 else
794 xRow->appendVoid( rProp );
796 else
798 // Not a Core Property! Maybe it's an Additional Core Property?!
800 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
802 xAdditionalPropSet =
803 rProvider->getAdditionalPropertySet( rContentId,
804 false );
805 bTriedToGetAdditionalPropSet = true;
808 if ( xAdditionalPropSet.is() )
810 if ( !xRow->appendPropertySetValue(
811 xAdditionalPropSet,
812 rProp ) )
814 // Append empty entry.
815 xRow->appendVoid( rProp );
818 else
820 // Append empty entry.
821 xRow->appendVoid( rProp );
826 else
828 // Append all Core Properties.
829 xRow->appendString (
830 beans::Property(
831 "ContentType",
833 cppu::UnoType<OUString>::get(),
834 beans::PropertyAttribute::BOUND
835 | beans::PropertyAttribute::READONLY ),
836 rData.aContentType );
837 xRow->appendString(
838 beans::Property(
839 "Title",
841 cppu::UnoType<OUString>::get(),
842 beans::PropertyAttribute::BOUND ),
843 rData.aTitle );
844 xRow->appendBoolean(
845 beans::Property(
846 "IsDocument",
848 cppu::UnoType<bool>::get(),
849 beans::PropertyAttribute::BOUND
850 | beans::PropertyAttribute::READONLY ),
851 rData.bIsDocument );
852 xRow->appendBoolean(
853 beans::Property(
854 "IsFolder",
856 cppu::UnoType<bool>::get(),
857 beans::PropertyAttribute::BOUND
858 | beans::PropertyAttribute::READONLY ),
859 rData.bIsFolder );
860 xRow->appendObject(
861 beans::Property(
862 "CreatableContentsInfo",
864 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
865 beans::PropertyAttribute::BOUND
866 | beans::PropertyAttribute::READONLY ),
867 uno::makeAny(
868 rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
869 xRow->appendString(
870 beans::Property(
871 "MediaType",
873 cppu::UnoType<OUString>::get(),
874 beans::PropertyAttribute::BOUND ),
875 rData.aMediaType );
877 // Properties only available for streams.
878 if ( rData.bIsDocument )
880 xRow->appendLong(
881 beans::Property(
882 "Size",
884 cppu::UnoType<sal_Int64>::get(),
885 beans::PropertyAttribute::BOUND
886 | beans::PropertyAttribute::READONLY ),
887 rData.nSize );
889 xRow->appendBoolean(
890 beans::Property(
891 "Compressed",
893 cppu::UnoType<bool>::get(),
894 beans::PropertyAttribute::BOUND ),
895 rData.bCompressed );
897 xRow->appendBoolean(
898 beans::Property(
899 "Encrypted",
901 cppu::UnoType<bool>::get(),
902 beans::PropertyAttribute::BOUND ),
903 rData.bEncrypted );
906 // Properties only available for root folder.
907 PackageUri aURI( rContentId );
908 if ( aURI.isRootFolder() )
910 xRow->appendBoolean(
911 beans::Property(
912 "HasEncryptedEntries",
914 cppu::UnoType<bool>::get(),
915 beans::PropertyAttribute::BOUND
916 | beans::PropertyAttribute::READONLY ),
917 rData.bHasEncryptedEntries );
920 // Append all Additional Core Properties.
922 uno::Reference< beans::XPropertySet > xSet =
923 rProvider->getAdditionalPropertySet( rContentId, false );
924 xRow->appendPropertySet( xSet );
927 return uno::Reference< sdbc::XRow >( xRow.get() );
931 uno::Reference< sdbc::XRow > Content::getPropertyValues(
932 const uno::Sequence< beans::Property >& rProperties )
934 osl::Guard< osl::Mutex > aGuard( m_aMutex );
935 return getPropertyValues( m_xContext,
936 rProperties,
937 m_aProps,
938 rtl::Reference<
939 ::ucbhelper::ContentProviderImplHelper >(
940 m_xProvider.get() ),
941 m_xIdentifier->getContentIdentifier() );
945 uno::Sequence< uno::Any > Content::setPropertyValues(
946 const uno::Sequence< beans::PropertyValue >& rValues,
947 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
949 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
951 uno::Sequence< uno::Any > aRet( rValues.getLength() );
952 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
953 sal_Int32 nChanged = 0;
955 beans::PropertyChangeEvent aEvent;
956 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
957 aEvent.Further = false;
958 // aEvent.PropertyName =
959 aEvent.PropertyHandle = -1;
960 // aEvent.OldValue =
961 // aEvent.NewValue =
963 const beans::PropertyValue* pValues = rValues.getConstArray();
964 sal_Int32 nCount = rValues.getLength();
966 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
967 bool bTriedToGetAdditionalPropSet = false;
968 bool bExchange = false;
969 bool bStore = false;
970 OUString aNewTitle;
971 sal_Int32 nTitlePos = -1;
973 for ( sal_Int32 n = 0; n < nCount; ++n )
975 const beans::PropertyValue& rValue = pValues[ n ];
977 if ( rValue.Name == "ContentType" )
979 // Read-only property!
980 aRet[ n ] <<= lang::IllegalAccessException(
981 "Property is read-only!",
982 static_cast< cppu::OWeakObject * >( this ) );
984 else if ( rValue.Name == "IsDocument" )
986 // Read-only property!
987 aRet[ n ] <<= lang::IllegalAccessException(
988 "Property is read-only!",
989 static_cast< cppu::OWeakObject * >( this ) );
991 else if ( rValue.Name == "IsFolder" )
993 // Read-only property!
994 aRet[ n ] <<= lang::IllegalAccessException(
995 "Property is read-only!",
996 static_cast< cppu::OWeakObject * >( this ) );
998 else if ( rValue.Name == "CreatableContentsInfo" )
1000 // Read-only property!
1001 aRet[ n ] <<= lang::IllegalAccessException(
1002 "Property is read-only!",
1003 static_cast< cppu::OWeakObject * >( this ) );
1005 else if ( rValue.Name == "Title" )
1007 if ( m_aUri.isRootFolder() )
1009 // Read-only property!
1010 aRet[ n ] <<= lang::IllegalAccessException(
1011 "Property is read-only!",
1012 static_cast< cppu::OWeakObject * >( this ) );
1014 else
1016 OUString aNewValue;
1017 if ( rValue.Value >>= aNewValue )
1019 // No empty titles!
1020 if ( !aNewValue.isEmpty() )
1022 if ( aNewValue != m_aProps.aTitle )
1024 // modified title -> modified URL -> exchange !
1025 if ( m_eState == PERSISTENT )
1026 bExchange = true;
1028 // new value will be set later...
1029 aNewTitle = aNewValue;
1031 // remember position within sequence of values
1032 // (for error handling).
1033 nTitlePos = n;
1036 else
1038 aRet[ n ] <<=
1039 lang::IllegalArgumentException(
1040 "Empty title not allowed!",
1041 static_cast< cppu::OWeakObject * >( this ),
1042 -1 );
1045 else
1047 aRet[ n ] <<=
1048 beans::IllegalTypeException(
1049 "Property value has wrong type!",
1050 static_cast< cppu::OWeakObject * >( this ) );
1054 else if ( rValue.Name == "MediaType" )
1056 OUString aNewValue;
1057 if ( rValue.Value >>= aNewValue )
1059 if ( aNewValue != m_aProps.aMediaType )
1061 aEvent.PropertyName = rValue.Name;
1062 aEvent.OldValue <<= m_aProps.aMediaType;
1063 aEvent.NewValue <<= aNewValue;
1065 m_aProps.aMediaType = aNewValue;
1066 nChanged++;
1067 bStore = true;
1068 m_nModifiedProps |= MEDIATYPE_MODIFIED;
1071 else
1073 aRet[ n ] <<= beans::IllegalTypeException(
1074 "Property value has wrong type!",
1075 static_cast< cppu::OWeakObject * >( this ) );
1078 else if ( rValue.Name == "Size" )
1080 // Read-only property!
1081 aRet[ n ] <<= lang::IllegalAccessException(
1082 "Property is read-only!",
1083 static_cast< cppu::OWeakObject * >( this ) );
1085 else if ( rValue.Name == "Compressed" )
1087 // Property only available for streams.
1088 if ( m_aProps.bIsDocument )
1090 bool bNewValue;
1091 if ( rValue.Value >>= bNewValue )
1093 if ( bNewValue != m_aProps.bCompressed )
1095 aEvent.PropertyName = rValue.Name;
1096 aEvent.OldValue <<= m_aProps.bCompressed;
1097 aEvent.NewValue <<= bNewValue;
1099 m_aProps.bCompressed = bNewValue;
1100 nChanged++;
1101 bStore = true;
1102 m_nModifiedProps |= COMPRESSED_MODIFIED;
1105 else
1107 aRet[ n ] <<= beans::IllegalTypeException(
1108 "Property value has wrong type!",
1109 static_cast< cppu::OWeakObject * >( this ) );
1112 else
1114 aRet[ n ] <<= beans::UnknownPropertyException(
1115 "Compressed only supported by streams!",
1116 static_cast< cppu::OWeakObject * >( this ) );
1119 else if ( rValue.Name == "Encrypted" )
1121 // Property only available for streams.
1122 if ( m_aProps.bIsDocument )
1124 bool bNewValue;
1125 if ( rValue.Value >>= bNewValue )
1127 if ( bNewValue != m_aProps.bEncrypted )
1129 aEvent.PropertyName = rValue.Name;
1130 aEvent.OldValue <<= m_aProps.bEncrypted;
1131 aEvent.NewValue <<= bNewValue;
1133 m_aProps.bEncrypted = bNewValue;
1134 nChanged++;
1135 bStore = true;
1136 m_nModifiedProps |= ENCRYPTED_MODIFIED;
1139 else
1141 aRet[ n ] <<= beans::IllegalTypeException(
1142 "Property value has wrong type!",
1143 static_cast< cppu::OWeakObject * >( this ) );
1146 else
1148 aRet[ n ] <<= beans::UnknownPropertyException(
1149 "Encrypted only supported by streams!",
1150 static_cast< cppu::OWeakObject * >( this ) );
1153 else if ( rValue.Name == "HasEncryptedEntries" )
1155 // Read-only property!
1156 aRet[ n ] <<= lang::IllegalAccessException(
1157 "Property is read-only!",
1158 static_cast< cppu::OWeakObject * >( this ) );
1160 else if ( rValue.Name == "EncryptionKey" )
1162 // @@@ This is a temporary solution. In the future submitting
1163 // the key should be done using an interaction handler!
1165 // Write-Only property. Only supported by root folder and streams
1166 // (all non-root folders of a package have the same encryption key).
1167 if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
1169 uno::Sequence < sal_Int8 > aNewValue;
1170 if ( rValue.Value >>= aNewValue )
1172 if ( aNewValue != m_aProps.aEncryptionKey )
1174 aEvent.PropertyName = rValue.Name;
1175 aEvent.OldValue <<= m_aProps.aEncryptionKey;
1176 aEvent.NewValue <<= aNewValue;
1178 m_aProps.aEncryptionKey = aNewValue;
1179 nChanged++;
1180 bStore = true;
1181 m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
1184 else
1186 aRet[ n ] <<= beans::IllegalTypeException(
1187 "Property value has wrong type!",
1188 static_cast< cppu::OWeakObject * >( this ) );
1191 else
1193 aRet[ n ] <<= beans::UnknownPropertyException(
1194 "EncryptionKey not supported by non-root folder!",
1195 static_cast< cppu::OWeakObject * >( this ) );
1198 else
1200 // Not a Core Property! Maybe it's an Additional Core Property?!
1202 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1204 xAdditionalPropSet = getAdditionalPropertySet( false );
1205 bTriedToGetAdditionalPropSet = true;
1208 if ( xAdditionalPropSet.is() )
1212 uno::Any aOldValue
1213 = xAdditionalPropSet->getPropertyValue( rValue.Name );
1214 if ( aOldValue != rValue.Value )
1216 xAdditionalPropSet->setPropertyValue(
1217 rValue.Name, rValue.Value );
1219 aEvent.PropertyName = rValue.Name;
1220 aEvent.OldValue = aOldValue;
1221 aEvent.NewValue = rValue.Value;
1223 aChanges.getArray()[ nChanged ] = aEvent;
1224 nChanged++;
1227 catch ( beans::UnknownPropertyException const & e )
1229 aRet[ n ] <<= e;
1231 catch ( lang::WrappedTargetException const & e )
1233 aRet[ n ] <<= e;
1235 catch ( beans::PropertyVetoException const & e )
1237 aRet[ n ] <<= e;
1239 catch ( lang::IllegalArgumentException const & e )
1241 aRet[ n ] <<= e;
1244 else
1246 aRet[ n ] <<= uno::Exception(
1247 "No property set for storing the value!",
1248 static_cast< cppu::OWeakObject * >( this ) );
1253 if ( bExchange )
1255 uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
1257 // Assemble new content identifier...
1258 OUString aNewURL = m_aUri.getParentUri() + "/";
1259 aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle );
1260 uno::Reference< ucb::XContentIdentifier > xNewId
1261 = new ::ucbhelper::ContentIdentifier( aNewURL );
1263 aGuard.clear();
1264 if ( exchangeIdentity( xNewId ) )
1266 // Adapt persistent data.
1267 renameData( xOldId, xNewId );
1269 // Adapt Additional Core Properties.
1270 renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1271 xNewId->getContentIdentifier() );
1273 else
1275 // Do not set new title!
1276 aNewTitle.clear();
1278 // Set error .
1279 aRet[ nTitlePos ] <<= uno::Exception(
1280 "Exchange failed!",
1281 static_cast< cppu::OWeakObject * >( this ) );
1285 if ( !aNewTitle.isEmpty() )
1287 aEvent.PropertyName = "Title";
1288 aEvent.OldValue <<= m_aProps.aTitle;
1289 aEvent.NewValue <<= aNewTitle;
1291 m_aProps.aTitle = aNewTitle;
1293 aChanges.getArray()[ nChanged ] = aEvent;
1294 nChanged++;
1297 if ( nChanged > 0 )
1299 // Save changes, if content was already made persistent.
1300 if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
1301 ( bStore && ( m_eState == PERSISTENT ) ) )
1303 if ( !storeData( uno::Reference< io::XInputStream >() ) )
1305 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1307 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1308 }));
1309 ucbhelper::cancelCommandExecution(
1310 ucb::IOErrorCode_CANT_WRITE,
1311 aArgs,
1312 xEnv,
1313 "Cannot store persistent data!",
1314 this );
1315 // Unreachable
1319 aGuard.clear();
1320 aChanges.realloc( nChanged );
1321 notifyPropertiesChange( aChanges );
1324 return aRet;
1328 uno::Any Content::open(
1329 const ucb::OpenCommandArgument2& rArg,
1330 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1332 if ( rArg.Mode == ucb::OpenMode::ALL ||
1333 rArg.Mode == ucb::OpenMode::FOLDERS ||
1334 rArg.Mode == ucb::OpenMode::DOCUMENTS )
1337 // open command for a folder content
1340 uno::Reference< ucb::XDynamicResultSet > xSet
1341 = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1342 return uno::makeAny( xSet );
1344 else
1347 // open command for a document content
1350 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1351 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1353 // Currently(?) unsupported.
1354 ucbhelper::cancelCommandExecution(
1355 uno::makeAny( ucb::UnsupportedOpenModeException(
1356 OUString(),
1357 static_cast< cppu::OWeakObject * >( this ),
1358 sal_Int16( rArg.Mode ) ) ),
1359 xEnv );
1360 // Unreachable
1363 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1364 if ( xOut.is() )
1366 // PUSH: write data into xOut
1368 uno::Reference< io::XInputStream > xIn = getInputStream();
1369 if ( !xIn.is() )
1371 // No interaction if we are not persistent!
1372 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1374 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1375 }));
1376 ucbhelper::cancelCommandExecution(
1377 ucb::IOErrorCode_CANT_READ,
1378 aArgs,
1379 m_eState == PERSISTENT
1380 ? xEnv
1381 : uno::Reference< ucb::XCommandEnvironment >(),
1382 "Got no data stream!",
1383 this );
1384 // Unreachable
1389 uno::Sequence< sal_Int8 > aBuffer;
1390 while (true)
1392 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1393 if (!nRead)
1394 break;
1395 aBuffer.realloc( nRead );
1396 xOut->writeBytes( aBuffer );
1399 xOut->closeOutput();
1401 catch ( io::NotConnectedException const & )
1403 // closeOutput, readSomeBytes, writeBytes
1405 catch ( io::BufferSizeExceededException const & )
1407 // closeOutput, readSomeBytes, writeBytes
1409 catch ( io::IOException const & )
1411 // closeOutput, readSomeBytes, writeBytes
1414 else
1416 uno::Reference< io::XActiveDataSink > xDataSink(
1417 rArg.Sink, uno::UNO_QUERY );
1418 if ( xDataSink.is() )
1420 // PULL: wait for client read
1422 uno::Reference< io::XInputStream > xIn = getInputStream();
1423 if ( !xIn.is() )
1425 // No interaction if we are not persistent!
1426 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1428 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1429 }));
1430 ucbhelper::cancelCommandExecution(
1431 ucb::IOErrorCode_CANT_READ,
1432 aArgs,
1433 m_eState == PERSISTENT
1434 ? xEnv
1435 : uno::Reference<
1436 ucb::XCommandEnvironment >(),
1437 "Got no data stream!",
1438 this );
1439 // Unreachable
1442 // Done.
1443 xDataSink->setInputStream( xIn );
1445 else
1447 // Note: aOpenCommand.Sink may contain an XStream
1448 // implementation. Support for this type of
1449 // sink is optional...
1450 ucbhelper::cancelCommandExecution(
1451 uno::makeAny(
1452 ucb::UnsupportedDataSinkException(
1453 OUString(),
1454 static_cast< cppu::OWeakObject * >( this ),
1455 rArg.Sink ) ),
1456 xEnv );
1457 // Unreachable
1462 return uno::Any();
1466 void Content::insert(
1467 const uno::Reference< io::XInputStream >& xStream,
1468 sal_Int32 nNameClashResolve,
1469 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1471 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1473 // Check, if all required properties were set.
1474 if ( isFolder() )
1476 // Required: Title
1478 if ( m_aProps.aTitle.isEmpty() )
1479 m_aProps.aTitle = m_aUri.getName();
1481 else
1483 // Required: rArg.Data
1485 if ( !xStream.is() )
1487 ucbhelper::cancelCommandExecution(
1488 uno::makeAny( ucb::MissingInputStreamException(
1489 OUString(),
1490 static_cast< cppu::OWeakObject * >( this ) ) ),
1491 xEnv );
1492 // Unreachable
1495 // Required: Title
1497 if ( m_aProps.aTitle.isEmpty() )
1498 m_aProps.aTitle = m_aUri.getName();
1501 OUString aNewURL = m_aUri.getParentUri();
1502 if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
1503 aNewURL += "/";
1504 aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
1505 PackageUri aNewUri( aNewURL );
1507 // Handle possible name clash...
1508 switch ( nNameClashResolve )
1510 // fail.
1511 case ucb::NameClash::ERROR:
1512 if ( hasData( aNewUri ) )
1514 ucbhelper::cancelCommandExecution(
1515 uno::makeAny( ucb::NameClashException(
1516 OUString(),
1517 static_cast< cppu::OWeakObject * >( this ),
1518 task::InteractionClassification_ERROR,
1519 m_aProps.aTitle ) ),
1520 xEnv );
1521 // Unreachable
1523 break;
1525 // replace (possibly) existing object.
1526 case ucb::NameClash::OVERWRITE:
1527 break;
1529 // "invent" a new valid title.
1530 case ucb::NameClash::RENAME:
1531 if ( hasData( aNewUri ) )
1533 sal_Int32 nTry = 0;
1537 OUString aNew = aNewUri.getUri() + "_";
1538 aNew += OUString::number( ++nTry );
1539 aNewUri.setUri( aNew );
1541 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1543 if ( nTry == 1000 )
1545 ucbhelper::cancelCommandExecution(
1546 uno::makeAny(
1547 ucb::UnsupportedNameClashException(
1548 "Unable to resolve name clash!",
1549 static_cast< cppu::OWeakObject * >( this ),
1550 nNameClashResolve ) ),
1551 xEnv );
1552 // Unreachable
1554 else
1556 m_aProps.aTitle += "_";
1557 m_aProps.aTitle += OUString::number( nTry );
1560 break;
1562 case ucb::NameClash::KEEP: // deprecated
1563 case ucb::NameClash::ASK:
1564 default:
1565 if ( hasData( aNewUri ) )
1567 ucbhelper::cancelCommandExecution(
1568 uno::makeAny(
1569 ucb::UnsupportedNameClashException(
1570 OUString(),
1571 static_cast< cppu::OWeakObject * >( this ),
1572 nNameClashResolve ) ),
1573 xEnv );
1574 // Unreachable
1576 break;
1579 // Identifier changed?
1580 bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
1582 if ( bNewId )
1584 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1585 m_aUri = aNewUri;
1588 if ( !storeData( xStream ) )
1590 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1592 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1593 }));
1594 ucbhelper::cancelCommandExecution(
1595 ucb::IOErrorCode_CANT_WRITE,
1596 aArgs,
1597 xEnv,
1598 "Cannot store persistent data!",
1599 this );
1600 // Unreachable
1603 m_eState = PERSISTENT;
1605 if ( bNewId )
1607 // Take over correct default values from underlying packager...
1608 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1609 loadData( m_pProvider,
1610 m_aUri,
1611 m_aProps,
1612 xXHierarchicalNameAccess );
1614 aGuard.clear();
1615 inserted();
1620 void Content::destroy(
1621 bool bDeletePhysical,
1622 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1624 // @@@ take care about bDeletePhysical -> trashcan support
1626 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1628 uno::Reference< ucb::XContent > xThis = this;
1630 // Persistent?
1631 if ( m_eState != PERSISTENT )
1633 ucbhelper::cancelCommandExecution(
1634 uno::makeAny( ucb::UnsupportedCommandException(
1635 "Not persistent!",
1636 static_cast< cppu::OWeakObject * >( this ) ) ),
1637 xEnv );
1638 // Unreachable
1641 m_eState = DEAD;
1643 aGuard.clear();
1644 deleted();
1646 if ( isFolder() )
1648 // Process instantiated children...
1650 ContentRefList aChildren;
1651 queryChildren( aChildren );
1653 for ( auto& rChild : aChildren )
1655 rChild->destroy( bDeletePhysical, xEnv );
1661 void Content::transfer(
1662 const ucb::TransferInfo& rInfo,
1663 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1665 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1667 // Persistent?
1668 if ( m_eState != PERSISTENT )
1670 ucbhelper::cancelCommandExecution(
1671 uno::makeAny( ucb::UnsupportedCommandException(
1672 "Not persistent!",
1673 static_cast< cppu::OWeakObject * >( this ) ) ),
1674 xEnv );
1675 // Unreachable
1678 // Is source a package content?
1679 if ( ( rInfo.SourceURL.isEmpty() ) ||
1680 ( rInfo.SourceURL.compareTo(
1681 m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
1683 ucbhelper::cancelCommandExecution(
1684 uno::makeAny( ucb::InteractiveBadTransferURLException(
1685 OUString(),
1686 static_cast< cppu::OWeakObject * >( this ) ) ),
1687 xEnv );
1688 // Unreachable
1691 // Is source not a parent of me / not me?
1692 OUString aId = m_aUri.getParentUri() + "/";
1694 if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1696 if ( aId.startsWith( rInfo.SourceURL ) )
1698 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1700 {"Uri", uno::Any(rInfo.SourceURL)}
1701 }));
1702 ucbhelper::cancelCommandExecution(
1703 ucb::IOErrorCode_RECURSIVE,
1704 aArgs,
1705 xEnv,
1706 "Target is equal to or is a child of source!",
1707 this );
1708 // Unreachable
1713 // 0) Obtain content object for source.
1716 uno::Reference< ucb::XContentIdentifier > xId
1717 = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1719 // Note: The static cast is okay here, because its sure that
1720 // m_xProvider is always the PackageContentProvider.
1721 rtl::Reference< Content > xSource;
1725 xSource = static_cast< Content * >(
1726 m_xProvider->queryContent( xId ).get() );
1728 catch ( ucb::IllegalIdentifierException const & )
1730 // queryContent
1733 if ( !xSource.is() )
1735 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1737 {"Uri", uno::Any(xId->getContentIdentifier())}
1738 }));
1739 ucbhelper::cancelCommandExecution(
1740 ucb::IOErrorCode_CANT_READ,
1741 aArgs,
1742 xEnv,
1743 "Cannot instantiate source object!",
1744 this );
1745 // Unreachable
1749 // 1) Create new child content.
1752 OUString aType = xSource->isFolder()
1753 ? getContentType( m_aUri.getScheme(), true )
1754 : getContentType( m_aUri.getScheme(), false );
1755 ucb::ContentInfo aContentInfo;
1756 aContentInfo.Type = aType;
1757 aContentInfo.Attributes = 0;
1759 // Note: The static cast is okay here, because its sure that
1760 // createNewContent always creates a Content.
1761 rtl::Reference< Content > xTarget
1762 = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1763 if ( !xTarget.is() )
1765 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1767 {"Folder", uno::Any(aId)}
1768 }));
1769 ucbhelper::cancelCommandExecution(
1770 ucb::IOErrorCode_CANT_CREATE,
1771 aArgs,
1772 xEnv,
1773 "XContentCreator::createNewContent failed!",
1774 this );
1775 // Unreachable
1779 // 2) Copy data from source content to child content.
1782 uno::Sequence< beans::Property > aSourceProps
1783 = xSource->getPropertySetInfo( xEnv )->getProperties();
1784 sal_Int32 nCount = aSourceProps.getLength();
1786 if ( nCount )
1788 bool bHadTitle = rInfo.NewTitle.isEmpty();
1790 // Get all source values.
1791 uno::Reference< sdbc::XRow > xRow
1792 = xSource->getPropertyValues( aSourceProps );
1794 uno::Sequence< beans::PropertyValue > aValues( nCount );
1795 beans::PropertyValue* pValues = aValues.getArray();
1797 const beans::Property* pProps = aSourceProps.getConstArray();
1798 for ( sal_Int32 n = 0; n < nCount; ++n )
1800 const beans::Property& rProp = pProps[ n ];
1801 beans::PropertyValue& rValue = pValues[ n ];
1803 rValue.Name = rProp.Name;
1804 rValue.Handle = rProp.Handle;
1806 if ( !bHadTitle && rProp.Name == "Title" )
1808 // Set new title instead of original.
1809 bHadTitle = true;
1810 rValue.Value <<= rInfo.NewTitle;
1812 else
1813 rValue.Value
1814 = xRow->getObject( n + 1,
1815 uno::Reference<
1816 container::XNameAccess >() );
1818 rValue.State = beans::PropertyState_DIRECT_VALUE;
1820 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1822 // Add Additional Core Property.
1825 xTarget->addProperty( rProp.Name,
1826 rProp.Attributes,
1827 rValue.Value );
1829 catch ( beans::PropertyExistException const & )
1832 catch ( beans::IllegalTypeException const & )
1835 catch ( lang::IllegalArgumentException const & )
1841 // Set target values.
1842 xTarget->setPropertyValues( aValues, xEnv );
1846 // 3) Commit (insert) child.
1849 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
1852 // 4) Transfer (copy) children of source.
1855 if ( xSource->isFolder() )
1857 uno::Reference< container::XEnumeration > xIter
1858 = xSource->getIterator();
1859 if ( xIter.is() )
1861 while ( xIter->hasMoreElements() )
1865 uno::Reference< container::XNamed > xNamed;
1866 xIter->nextElement() >>= xNamed;
1868 if ( !xNamed.is() )
1870 OSL_FAIL( "Content::transfer - Got no XNamed!" );
1871 break;
1874 OUString aName = xNamed->getName();
1876 if ( aName.isEmpty() )
1878 OSL_FAIL( "Content::transfer - Empty name!" );
1879 break;
1882 OUString aChildId = xId->getContentIdentifier();
1883 if ( ( aChildId.lastIndexOf( '/' ) + 1 )
1884 != aChildId.getLength() )
1885 aChildId += "/";
1887 aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
1889 ucb::TransferInfo aInfo;
1890 aInfo.MoveData = false;
1891 aInfo.NewTitle.clear();
1892 aInfo.SourceURL = aChildId;
1893 aInfo.NameClash = rInfo.NameClash;
1895 // Transfer child to target.
1896 xTarget->transfer( aInfo, xEnv );
1898 catch ( container::NoSuchElementException const & )
1901 catch ( lang::WrappedTargetException const & )
1909 // 5) Destroy source ( when moving only ) .
1912 if ( rInfo.MoveData )
1914 xSource->destroy( true, xEnv );
1916 // Remove all persistent data of source and its children.
1917 if ( !xSource->removeData() )
1919 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1921 {"Uri", uno::Any(xSource->m_xIdentifier->getContentIdentifier())}
1922 }));
1923 ucbhelper::cancelCommandExecution(
1924 ucb::IOErrorCode_CANT_WRITE,
1925 aArgs,
1926 xEnv,
1927 "Cannot remove persistent data of source object!",
1928 this );
1929 // Unreachable
1932 // Remove own and all children's Additional Core Properties.
1933 xSource->removeAdditionalPropertySet();
1938 bool Content::exchangeIdentity(
1939 const uno::Reference< ucb::XContentIdentifier >& xNewId )
1941 if ( !xNewId.is() )
1942 return false;
1944 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1946 uno::Reference< ucb::XContent > xThis = this;
1948 // Already persistent?
1949 if ( m_eState != PERSISTENT )
1951 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
1952 return false;
1955 // Exchange own identitity.
1957 // Fail, if a content with given id already exists.
1958 PackageUri aNewUri( xNewId->getContentIdentifier() );
1959 if ( !hasData( aNewUri ) )
1961 OUString aOldURL = m_xIdentifier->getContentIdentifier();
1963 aGuard.clear();
1964 if ( exchange( xNewId ) )
1966 m_aUri = aNewUri;
1967 if ( isFolder() )
1969 // Process instantiated children...
1971 ContentRefList aChildren;
1972 queryChildren( aChildren );
1974 for ( const auto& rChild : aChildren )
1976 ContentRef xChild = rChild;
1978 // Create new content identifier for the child...
1979 uno::Reference< ucb::XContentIdentifier > xOldChildId
1980 = xChild->getIdentifier();
1981 OUString aOldChildURL
1982 = xOldChildId->getContentIdentifier();
1983 OUString aNewChildURL
1984 = aOldChildURL.replaceAt(
1986 aOldURL.getLength(),
1987 xNewId->getContentIdentifier() );
1988 uno::Reference< ucb::XContentIdentifier > xNewChildId
1989 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
1991 if ( !xChild->exchangeIdentity( xNewChildId ) )
1992 return false;
1995 return true;
1999 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2000 return false;
2004 void Content::queryChildren( ContentRefList& rChildren )
2006 // Obtain a list with a snapshot of all currently instantiated contents
2007 // from provider and extract the contents which are direct children
2008 // of this content.
2010 ::ucbhelper::ContentRefList aAllContents;
2011 m_xProvider->queryExistingContents( aAllContents );
2013 OUString aURL = m_xIdentifier->getContentIdentifier();
2015 OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2016 "Content::queryChildren - Invalid URL!" );
2018 aURL += "/";
2020 sal_Int32 nLen = aURL.getLength();
2022 for ( const auto& rContent : aAllContents )
2024 ::ucbhelper::ContentImplHelperRef xChild = rContent;
2025 OUString aChildURL
2026 = xChild->getIdentifier()->getContentIdentifier();
2028 // Is aURL a prefix of aChildURL?
2029 if ( ( aChildURL.getLength() > nLen ) &&
2030 ( aChildURL.startsWith( aURL ) ) )
2032 if ( aChildURL.indexOf( '/', nLen ) == -1 )
2034 // No further slashes. It's a child!
2035 rChildren.emplace_back(
2036 static_cast< Content * >( xChild.get() ) );
2043 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2044 const PackageUri& rURI )
2046 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2048 if ( rURI.getPackage() == m_aUri.getPackage() )
2050 if ( !m_xPackage.is() )
2051 m_xPackage = m_pProvider->createPackage( m_aUri );
2053 return m_xPackage;
2056 return m_pProvider->createPackage( rURI );
2060 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2062 return getPackage( m_aUri );
2066 // static
2067 bool Content::hasData(
2068 ContentProvider* pProvider,
2069 const PackageUri& rURI,
2070 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2072 rxPackage = pProvider->createPackage( rURI );
2073 return rxPackage->hasByHierarchicalName( rURI.getPath() );
2077 bool Content::hasData( const PackageUri& rURI )
2079 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2081 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2082 if ( rURI.getPackage() == m_aUri.getPackage() )
2084 xPackage = getPackage();
2085 return xPackage->hasByHierarchicalName( rURI.getPath() );
2088 return hasData( m_pProvider, rURI, xPackage );
2092 //static
2093 bool Content::loadData(
2094 ContentProvider* pProvider,
2095 const PackageUri& rURI,
2096 ContentProperties& rProps,
2097 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2099 rxPackage = pProvider->createPackage( rURI );
2101 if ( rURI.isRootFolder() )
2103 // Properties available only from package
2104 uno::Reference< beans::XPropertySet > xPackagePropSet(
2105 rxPackage, uno::UNO_QUERY );
2107 OSL_ENSURE( xPackagePropSet.is(),
2108 "Content::loadData - "
2109 "Got no XPropertySet interface from package!" );
2111 if ( xPackagePropSet.is() )
2113 // HasEncryptedEntries (only available at root folder)
2116 uno::Any aHasEncryptedEntries
2117 = xPackagePropSet->getPropertyValue( "HasEncryptedEntries" );
2118 if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2120 OSL_FAIL( "Content::loadData - "
2121 "Got no HasEncryptedEntries value!" );
2122 return false;
2125 catch ( beans::UnknownPropertyException const & )
2127 OSL_FAIL( "Content::loadData - "
2128 "Got no HasEncryptedEntries value!" );
2129 return false;
2131 catch ( lang::WrappedTargetException const & )
2133 OSL_FAIL( "Content::loadData - "
2134 "Got no HasEncryptedEntries value!" );
2135 return false;
2140 if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2141 return false;
2145 uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2146 if ( aEntry.hasValue() )
2148 uno::Reference< beans::XPropertySet > xPropSet;
2149 aEntry >>= xPropSet;
2151 if ( !xPropSet.is() )
2153 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2154 return false;
2157 // Title
2158 rProps.aTitle = rURI.getName();
2160 // MediaType
2163 uno::Any aMediaType = xPropSet->getPropertyValue("MediaType");
2164 if ( !( aMediaType >>= rProps.aMediaType ) )
2166 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2167 return false;
2170 catch ( beans::UnknownPropertyException const & )
2172 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2173 return false;
2175 catch ( lang::WrappedTargetException const & )
2177 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2178 return false;
2181 uno::Reference< container::XEnumerationAccess > xEnumAccess;
2182 aEntry >>= xEnumAccess;
2184 // ContentType / IsFolder / IsDocument
2185 if ( xEnumAccess.is() )
2187 // folder
2188 rProps.aContentType = getContentType( rURI.getScheme(), true );
2189 rProps.bIsDocument = false;
2190 rProps.bIsFolder = true;
2192 else
2194 // stream
2195 rProps.aContentType = getContentType( rURI.getScheme(), false );
2196 rProps.bIsDocument = true;
2197 rProps.bIsFolder = false;
2200 if ( rProps.bIsDocument )
2202 // Size ( only available for streams )
2205 uno::Any aSize = xPropSet->getPropertyValue("Size");
2206 if ( !( aSize >>= rProps.nSize ) )
2208 OSL_FAIL( "Content::loadData - Got no Size value!" );
2209 return false;
2212 catch ( beans::UnknownPropertyException const & )
2214 OSL_FAIL( "Content::loadData - Got no Size value!" );
2215 return false;
2217 catch ( lang::WrappedTargetException const & )
2219 OSL_FAIL( "Content::loadData - Got no Size value!" );
2220 return false;
2223 // Compressed ( only available for streams )
2226 uno::Any aCompressed = xPropSet->getPropertyValue("Compressed");
2227 if ( !( aCompressed >>= rProps.bCompressed ) )
2229 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2230 return false;
2233 catch ( beans::UnknownPropertyException const & )
2235 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2236 return false;
2238 catch ( lang::WrappedTargetException const & )
2240 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2241 return false;
2244 // Encrypted ( only available for streams )
2247 uno::Any aEncrypted = xPropSet->getPropertyValue("Encrypted");
2248 if ( !( aEncrypted >>= rProps.bEncrypted ) )
2250 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2251 return false;
2254 catch ( beans::UnknownPropertyException const & )
2256 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2257 return false;
2259 catch ( lang::WrappedTargetException const & )
2261 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2262 return false;
2265 return true;
2268 catch ( container::NoSuchElementException const & )
2270 // getByHierarchicalName
2273 return false;
2277 void Content::renameData(
2278 const uno::Reference< ucb::XContentIdentifier >& xOldId,
2279 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2281 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2283 PackageUri aURI( xOldId->getContentIdentifier() );
2284 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2285 aURI );
2287 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2288 return;
2292 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2293 uno::Reference< container::XNamed > xNamed;
2294 aEntry >>= xNamed;
2296 if ( !xNamed.is() )
2298 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2299 return;
2302 PackageUri aNewURI( xNewId->getContentIdentifier() );
2304 // No success indicator!? No return value / exceptions specified.
2305 xNamed->setName( aNewURI.getName() );
2307 catch ( container::NoSuchElementException const & )
2309 // getByHierarchicalName
2314 bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2316 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2318 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2320 uno::Reference< beans::XPropertySet > xPackagePropSet(
2321 xNA, uno::UNO_QUERY );
2322 OSL_ENSURE( xPackagePropSet.is(),
2323 "Content::storeData - "
2324 "Got no XPropertySet interface from package!" );
2326 if ( !xPackagePropSet.is() )
2327 return false;
2329 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2331 if ( m_aUri.isRootFolder() )
2333 // Property available only from package and from streams (see below)
2336 xPackagePropSet->setPropertyValue(
2337 "EncryptionKey",
2338 uno::makeAny( m_aProps.aEncryptionKey ) );
2339 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2341 catch ( beans::UnknownPropertyException const & )
2343 // setPropertyValue
2345 catch ( beans::PropertyVetoException const & )
2347 // setPropertyValue
2349 catch ( lang::IllegalArgumentException const & )
2351 // setPropertyValue
2353 catch ( lang::WrappedTargetException const & )
2355 // setPropertyValue
2360 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2362 // if ( !bCreate )
2363 // return sal_True;
2367 // Create new resource...
2368 uno::Reference< lang::XSingleServiceFactory > xFac(
2369 xNA, uno::UNO_QUERY );
2370 if ( !xFac.is() )
2372 OSL_FAIL( "Content::storeData - "
2373 "Got no XSingleServiceFactory interface!" );
2374 return false;
2377 uno::Sequence< uno::Any > aArgs( 1 );
2378 aArgs[ 0 ] <<= isFolder();
2380 uno::Reference< uno::XInterface > xNew
2381 = xFac->createInstanceWithArguments( aArgs );
2383 if ( !xNew.is() )
2385 OSL_FAIL( "Content::storeData - createInstance failed!" );
2386 return false;
2389 PackageUri aParentUri( getParentURL() );
2390 uno::Any aEntry
2391 = xNA->getByHierarchicalName( aParentUri.getPath() );
2392 uno::Reference< container::XNameContainer > xParentContainer;
2393 aEntry >>= xParentContainer;
2395 if ( !xParentContainer.is() )
2397 OSL_FAIL( "Content::storeData - "
2398 "Got no XNameContainer interface!" );
2399 return false;
2402 xParentContainer->insertByName( m_aProps.aTitle,
2403 uno::makeAny( xNew ) );
2405 catch ( lang::IllegalArgumentException const & )
2407 // insertByName
2408 OSL_FAIL( "Content::storeData - insertByName failed!" );
2409 return false;
2411 catch ( uno::RuntimeException const & )
2413 throw;
2415 catch ( container::ElementExistException const & )
2417 // insertByName
2418 OSL_FAIL( "Content::storeData - insertByName failed!" );
2419 return false;
2421 catch ( lang::WrappedTargetException const & )
2423 // insertByName
2424 OSL_FAIL( "Content::storeData - insertByName failed!" );
2425 return false;
2427 catch ( container::NoSuchElementException const & )
2429 // getByHierarchicalName
2430 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2431 return false;
2433 catch ( uno::Exception const & )
2435 // createInstanceWithArguments
2436 OSL_FAIL( "Content::storeData - Error!" );
2437 return false;
2441 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2442 return false;
2446 uno::Reference< beans::XPropertySet > xPropSet;
2447 xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2449 if ( !xPropSet.is() )
2451 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2452 return false;
2456 // Store property values...
2459 if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2461 xPropSet->setPropertyValue(
2462 "MediaType",
2463 uno::makeAny( m_aProps.aMediaType ) );
2464 m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2467 if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2469 if ( !isFolder() )
2470 xPropSet->setPropertyValue(
2471 "Compressed",
2472 uno::makeAny( m_aProps.bCompressed ) );
2474 m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2477 if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2479 if ( !isFolder() )
2480 xPropSet->setPropertyValue(
2481 "Encrypted",
2482 uno::makeAny( m_aProps.bEncrypted ) );
2484 m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2487 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2489 if ( !isFolder() )
2490 xPropSet->setPropertyValue(
2491 "EncryptionKey",
2492 uno::makeAny( m_aProps.aEncryptionKey ) );
2494 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2498 // Store data stream...
2501 if ( xStream.is() && !isFolder() )
2503 uno::Reference< io::XActiveDataSink > xSink(
2504 xPropSet, uno::UNO_QUERY );
2506 if ( !xSink.is() )
2508 OSL_FAIL( "Content::storeData - "
2509 "Got no XActiveDataSink interface!" );
2510 return false;
2513 xSink->setInputStream( xStream );
2516 return true;
2518 catch ( container::NoSuchElementException const & )
2520 // getByHierarchicalName
2522 catch ( beans::UnknownPropertyException const & )
2524 // setPropertyValue
2526 catch ( beans::PropertyVetoException const & )
2528 // setPropertyValue
2530 catch ( lang::IllegalArgumentException const & )
2532 // setPropertyValue
2534 catch ( lang::WrappedTargetException const & )
2536 // setPropertyValue
2539 OSL_FAIL( "Content::storeData - Error!" );
2540 return false;
2544 bool Content::removeData()
2546 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2548 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2550 PackageUri aParentUri( getParentURL() );
2551 if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2552 return false;
2556 uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2557 uno::Reference< container::XNameContainer > xContainer;
2558 aEntry >>= xContainer;
2560 if ( !xContainer.is() )
2562 OSL_FAIL( "Content::removeData - "
2563 "Got no XNameContainer interface!" );
2564 return false;
2567 xContainer->removeByName( m_aUri.getName() );
2568 return true;
2570 catch ( container::NoSuchElementException const & )
2572 // getByHierarchicalName, removeByName
2574 catch ( lang::WrappedTargetException const & )
2576 // removeByName
2579 OSL_FAIL( "Content::removeData - Error!" );
2580 return false;
2584 bool Content::flushData()
2586 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2588 // Note: XChangesBatch is only implemented by the package itself, not
2589 // by the single entries. Maybe this has to change...
2591 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2593 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2594 if ( !xBatch.is() )
2596 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2597 return false;
2602 xBatch->commitChanges();
2603 return true;
2605 catch ( lang::WrappedTargetException const & )
2609 OSL_FAIL( "Content::flushData - Error!" );
2610 return false;
2614 uno::Reference< io::XInputStream > Content::getInputStream()
2616 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2618 uno::Reference< io::XInputStream > xStream;
2619 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2621 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2622 return xStream;
2626 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2627 uno::Reference< io::XActiveDataSink > xSink;
2628 aEntry >>= xSink;
2630 if ( !xSink.is() )
2632 OSL_FAIL( "Content::getInputStream - "
2633 "Got no XActiveDataSink interface!" );
2634 return xStream;
2637 xStream = xSink->getInputStream();
2639 OSL_ENSURE( xStream.is(),
2640 "Content::getInputStream - Got no stream!" );
2642 catch ( container::NoSuchElementException const & )
2644 // getByHierarchicalName
2647 return xStream;
2651 uno::Reference< container::XEnumeration > Content::getIterator()
2653 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2655 uno::Reference< container::XEnumeration > xIter;
2656 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2658 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2659 return xIter;
2663 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2664 uno::Reference< container::XEnumerationAccess > xIterFac;
2665 aEntry >>= xIterFac;
2667 if ( !xIterFac.is() )
2669 OSL_FAIL( "Content::getIterator - "
2670 "Got no XEnumerationAccess interface!" );
2671 return xIter;
2674 xIter = xIterFac->createEnumeration();
2676 OSL_ENSURE( xIter.is(),
2677 "Content::getIterator - Got no iterator!" );
2679 catch ( container::NoSuchElementException const & )
2681 // getByHierarchicalName
2684 return xIter;
2687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */