tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / ucb / source / ucp / package / pkgcontent.cxx
blob818dafeaaec4bc9c8e329585a99e142ff4e3ac02
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 <sal/config.h>
27 #include <string_view>
29 #include <osl/diagnose.h>
31 #include <rtl/ustring.hxx>
32 #include <com/sun/star/beans/IllegalTypeException.hpp>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <com/sun/star/beans/PropertyExistException.hpp>
35 #include <com/sun/star/beans/PropertyState.hpp>
36 #include <com/sun/star/container/XEnumerationAccess.hpp>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/io/BufferSizeExceededException.hpp>
41 #include <com/sun/star/io/NotConnectedException.hpp>
42 #include <com/sun/star/io/XActiveDataSink.hpp>
43 #include <com/sun/star/io/XOutputStream.hpp>
44 #include <com/sun/star/lang/IllegalAccessException.hpp>
45 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
46 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
47 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
48 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
49 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
50 #include <com/sun/star/ucb/NameClash.hpp>
51 #include <com/sun/star/ucb/NameClashException.hpp>
52 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
53 #include <com/sun/star/ucb/OpenMode.hpp>
54 #include <com/sun/star/ucb/TransferInfo.hpp>
55 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
56 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
57 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
58 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
59 #include <com/sun/star/ucb/XCommandInfo.hpp>
60 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
61 #include <com/sun/star/util/XChangesBatch.hpp>
62 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
63 #include <com/sun/star/uno/Any.hxx>
64 #include <com/sun/star/uno/Sequence.hxx>
65 #include <comphelper/propertysequence.hxx>
66 #include <cppuhelper/queryinterface.hxx>
67 #include <ucbhelper/contentidentifier.hxx>
68 #include <ucbhelper/propertyvalueset.hxx>
69 #include <ucbhelper/cancelcommandexecution.hxx>
70 #include <ucbhelper/macros.hxx>
71 #include <utility>
72 #include "pkgcontent.hxx"
73 #include "pkgprovider.hxx"
74 #include "pkgresultset.hxx"
76 #include "../inc/urihelper.hxx"
78 using namespace com::sun::star;
79 using namespace package_ucp;
81 #define NONE_MODIFIED sal_uInt32( 0x00 )
82 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
83 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
84 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
85 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
88 // ContentProperties Implementation.
91 ContentProperties::ContentProperties( const OUString& rContentType )
92 : aContentType( rContentType ),
93 nSize( 0 ),
94 bCompressed( true ),
95 bEncrypted( false ),
96 bHasEncryptedEntries( false )
98 bIsFolder = rContentType == PACKAGE_FOLDER_CONTENT_TYPE || rContentType == PACKAGE_ZIP_FOLDER_CONTENT_TYPE;
99 bIsDocument = !bIsFolder;
101 OSL_ENSURE( bIsFolder || rContentType == PACKAGE_STREAM_CONTENT_TYPE || rContentType == PACKAGE_ZIP_STREAM_CONTENT_TYPE,
102 "ContentProperties::ContentProperties - Unknown type!" );
106 uno::Sequence< ucb::ContentInfo >
107 ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
109 if ( bIsFolder )
111 uno::Sequence< beans::Property > aProps( 1 );
112 aProps.getArray()[ 0 ] = beans::Property(
113 u"Title"_ustr,
115 cppu::UnoType<OUString>::get(),
116 beans::PropertyAttribute::BOUND );
118 uno::Sequence< ucb::ContentInfo > aSeq( 2 );
120 // Folder.
121 aSeq.getArray()[ 0 ].Type
122 = Content::getContentType( rUri.getScheme(), true );
123 aSeq.getArray()[ 0 ].Attributes
124 = ucb::ContentInfoAttribute::KIND_FOLDER;
125 aSeq.getArray()[ 0 ].Properties = aProps;
127 // Stream.
128 aSeq.getArray()[ 1 ].Type
129 = Content::getContentType( rUri.getScheme(), false );
130 aSeq.getArray()[ 1 ].Attributes
131 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
132 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
133 aSeq.getArray()[ 1 ].Properties = std::move(aProps);
135 return aSeq;
137 else
139 return uno::Sequence< ucb::ContentInfo >( 0 );
144 // Content Implementation.
147 // static ( "virtual" ctor )
148 rtl::Reference<Content> Content::create(
149 const uno::Reference< uno::XComponentContext >& rxContext,
150 ContentProvider* pProvider,
151 const uno::Reference< ucb::XContentIdentifier >& Identifier )
153 OUString aURL = Identifier->getContentIdentifier();
154 PackageUri aURI( aURL );
155 ContentProperties aProps;
156 uno::Reference< container::XHierarchicalNameAccess > xPackage;
158 if ( loadData( pProvider, aURI, aProps, xPackage ) )
160 // resource exists
162 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
163 if ( ( nLastSlash + 1 ) == aURL.getLength() )
165 // Client explicitly requested a folder!
166 if ( !aProps.bIsFolder )
167 return nullptr;
170 uno::Reference< ucb::XContentIdentifier > xId
171 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
172 return new Content( rxContext, pProvider, xId, xPackage, std::move(aURI), std::move(aProps) );
174 else
176 // resource doesn't exist
178 bool bFolder = false;
180 // Guess type according to URI.
181 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
182 if ( ( nLastSlash + 1 ) == aURL.getLength() )
183 bFolder = true;
185 uno::Reference< ucb::XContentIdentifier > xId
186 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
188 ucb::ContentInfo aInfo;
189 if ( bFolder || aURI.isRootFolder() )
190 aInfo.Type = getContentType( aURI.getScheme(), true );
191 else
192 aInfo.Type = getContentType( aURI.getScheme(), false );
194 return new Content( rxContext, pProvider, xId, xPackage, std::move(aURI), std::move(aInfo) );
199 // static ( "virtual" ctor )
200 rtl::Reference<Content> Content::create(
201 const uno::Reference< uno::XComponentContext >& rxContext,
202 ContentProvider* pProvider,
203 const uno::Reference< ucb::XContentIdentifier >& Identifier,
204 const ucb::ContentInfo& Info )
206 if ( Info.Type.isEmpty() )
207 return nullptr;
209 PackageUri aURI( Identifier->getContentIdentifier() );
211 if ( !Info.Type.equalsIgnoreAsciiCase(
212 getContentType( aURI.getScheme(), true ) ) &&
213 !Info.Type.equalsIgnoreAsciiCase(
214 getContentType( aURI.getScheme(), false ) ) )
215 return nullptr;
217 uno::Reference< container::XHierarchicalNameAccess > xPackage = pProvider->createPackage( aURI );
219 uno::Reference< ucb::XContentIdentifier > xId
220 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
221 return new Content( rxContext, pProvider, xId, xPackage, std::move(aURI), Info );
225 // static
226 OUString Content::getContentType(
227 std::u16string_view aScheme, bool bFolder )
229 return ( OUString::Concat("application/")
230 + aScheme
231 + ( bFolder
232 ? std::u16string_view(u"-folder")
233 : std::u16string_view(u"-stream") ) );
237 Content::Content(
238 const uno::Reference< uno::XComponentContext >& rxContext,
239 ContentProvider* pProvider,
240 const uno::Reference< ucb::XContentIdentifier >& Identifier,
241 uno::Reference< container::XHierarchicalNameAccess > Package,
242 PackageUri aUri,
243 ContentProperties aProps )
244 : ContentImplHelper( rxContext, pProvider, Identifier ),
245 m_aUri(std::move( aUri )),
246 m_aProps(std::move( aProps )),
247 m_eState( PERSISTENT ),
248 m_xPackage(std::move( Package )),
249 m_pProvider( pProvider ),
250 m_nModifiedProps( NONE_MODIFIED )
255 Content::Content(
256 const uno::Reference< uno::XComponentContext >& rxContext,
257 ContentProvider* pProvider,
258 const uno::Reference< ucb::XContentIdentifier >& Identifier,
259 uno::Reference< container::XHierarchicalNameAccess > Package,
260 PackageUri aUri,
261 const ucb::ContentInfo& Info )
262 : ContentImplHelper( rxContext, pProvider, Identifier ),
263 m_aUri(std::move( aUri )),
264 m_aProps( Info.Type ),
265 m_eState( TRANSIENT ),
266 m_xPackage(std::move( Package )),
267 m_pProvider( pProvider ),
268 m_nModifiedProps( NONE_MODIFIED )
273 // virtual
274 Content::~Content()
279 // XInterface methods.
282 // virtual
283 void SAL_CALL Content::acquire()
284 noexcept
286 ContentImplHelper::acquire();
290 // virtual
291 void SAL_CALL Content::release()
292 noexcept
294 ContentImplHelper::release();
298 // virtual
299 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
301 uno::Any aRet;
303 if ( isFolder() )
304 aRet = cppu::queryInterface(
305 rType, static_cast< ucb::XContentCreator * >( this ) );
307 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
311 // XTypeProvider methods.
314 XTYPEPROVIDER_COMMON_IMPL( Content );
317 // virtual
318 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
320 if ( isFolder() )
322 static cppu::OTypeCollection s_aFolderTypes(
323 CPPU_TYPE_REF( lang::XTypeProvider ),
324 CPPU_TYPE_REF( lang::XServiceInfo ),
325 CPPU_TYPE_REF( lang::XComponent ),
326 CPPU_TYPE_REF( ucb::XContent ),
327 CPPU_TYPE_REF( ucb::XCommandProcessor ),
328 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
329 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
330 CPPU_TYPE_REF( beans::XPropertyContainer ),
331 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
332 CPPU_TYPE_REF( container::XChild ),
333 CPPU_TYPE_REF( ucb::XContentCreator ) );
335 return s_aFolderTypes.getTypes();
338 else
340 static cppu::OTypeCollection s_aDocumentTypes(
341 CPPU_TYPE_REF( lang::XTypeProvider ),
342 CPPU_TYPE_REF( lang::XServiceInfo ),
343 CPPU_TYPE_REF( lang::XComponent ),
344 CPPU_TYPE_REF( ucb::XContent ),
345 CPPU_TYPE_REF( ucb::XCommandProcessor ),
346 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
347 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
348 CPPU_TYPE_REF( beans::XPropertyContainer ),
349 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
350 CPPU_TYPE_REF( container::XChild ) );
352 return s_aDocumentTypes.getTypes();
357 // XServiceInfo methods.
360 // virtual
361 OUString SAL_CALL Content::getImplementationName()
363 return u"com.sun.star.comp.ucb.PackageContent"_ustr;
367 // virtual
368 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
370 return { isFolder()? u"com.sun.star.ucb.PackageFolderContent"_ustr:u"com.sun.star.ucb.PackageStreamContent"_ustr } ;
374 // XContent methods.
377 // virtual
378 OUString SAL_CALL Content::getContentType()
380 return m_aProps.aContentType;
384 // XCommandProcessor methods.
387 // virtual
388 uno::Any SAL_CALL Content::execute(
389 const ucb::Command& aCommand,
390 sal_Int32 /*CommandId*/,
391 const uno::Reference< ucb::XCommandEnvironment >& Environment )
393 uno::Any aRet;
395 if ( aCommand.Name == "getPropertyValues" )
398 // getPropertyValues
401 uno::Sequence< beans::Property > Properties;
402 if ( !( aCommand.Argument >>= Properties ) )
404 ucbhelper::cancelCommandExecution(
405 uno::Any( lang::IllegalArgumentException(
406 u"Wrong argument type!"_ustr,
407 getXWeak(),
408 -1 ) ),
409 Environment );
410 // Unreachable
413 aRet <<= getPropertyValues( Properties );
415 else if ( aCommand.Name == "setPropertyValues" )
418 // setPropertyValues
421 uno::Sequence< beans::PropertyValue > aProperties;
422 if ( !( aCommand.Argument >>= aProperties ) )
424 ucbhelper::cancelCommandExecution(
425 uno::Any( lang::IllegalArgumentException(
426 u"Wrong argument type!"_ustr,
427 getXWeak(),
428 -1 ) ),
429 Environment );
430 // Unreachable
433 if ( !aProperties.hasElements() )
435 ucbhelper::cancelCommandExecution(
436 uno::Any( lang::IllegalArgumentException(
437 u"No properties!"_ustr,
438 getXWeak(),
439 -1 ) ),
440 Environment );
441 // Unreachable
444 aRet <<= setPropertyValues( aProperties, Environment );
446 else if ( aCommand.Name == "getPropertySetInfo" )
449 // getPropertySetInfo
452 // Note: Implemented by base class.
453 aRet <<= getPropertySetInfo( Environment );
455 else if ( aCommand.Name == "getCommandInfo" )
458 // getCommandInfo
461 // Note: Implemented by base class.
462 aRet <<= getCommandInfo( Environment );
464 else if ( aCommand.Name == "open" )
467 // open
470 ucb::OpenCommandArgument2 aOpenCommand;
471 if ( !( aCommand.Argument >>= aOpenCommand ) )
473 ucbhelper::cancelCommandExecution(
474 uno::Any( lang::IllegalArgumentException(
475 u"Wrong argument type!"_ustr,
476 getXWeak(),
477 -1 ) ),
478 Environment );
479 // Unreachable
482 aRet = open( aOpenCommand, Environment );
484 else if ( !m_aUri.isRootFolder() && aCommand.Name == "insert" )
487 // insert
490 ucb::InsertCommandArgument aArg;
491 if ( !( aCommand.Argument >>= aArg ) )
493 ucbhelper::cancelCommandExecution(
494 uno::Any( lang::IllegalArgumentException(
495 u"Wrong argument type!"_ustr,
496 getXWeak(),
497 -1 ) ),
498 Environment );
499 // Unreachable
502 sal_Int32 nNameClash = aArg.ReplaceExisting
503 ? ucb::NameClash::OVERWRITE
504 : ucb::NameClash::ERROR;
505 insert( aArg.Data, nNameClash, Environment );
507 else if ( !m_aUri.isRootFolder() && aCommand.Name == "delete" )
510 // delete
513 bool bDeletePhysical = false;
514 aCommand.Argument >>= bDeletePhysical;
515 destroy( bDeletePhysical, Environment );
517 // Remove own and all children's persistent data.
518 if ( !removeData() )
520 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
522 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
523 }));
524 ucbhelper::cancelCommandExecution(
525 ucb::IOErrorCode_CANT_WRITE,
526 aArgs,
527 Environment,
528 u"Cannot remove persistent data!"_ustr,
529 this );
530 // Unreachable
533 // Remove own and all children's Additional Core Properties.
534 removeAdditionalPropertySet();
536 else if ( aCommand.Name == "transfer" )
539 // transfer
540 // ( Not available at stream objects )
543 ucb::TransferInfo aInfo;
544 if ( !( aCommand.Argument >>= aInfo ) )
546 ucbhelper::cancelCommandExecution(
547 uno::Any( lang::IllegalArgumentException(
548 u"Wrong argument type!"_ustr,
549 getXWeak(),
550 -1 ) ),
551 Environment );
552 // Unreachable
555 transfer( aInfo, Environment );
557 else if ( aCommand.Name == "createNewContent" && isFolder() )
560 // createNewContent
561 // ( Not available at stream objects )
564 ucb::ContentInfo aInfo;
565 if ( !( aCommand.Argument >>= aInfo ) )
567 OSL_FAIL( "Wrong argument type!" );
568 ucbhelper::cancelCommandExecution(
569 uno::Any( lang::IllegalArgumentException(
570 u"Wrong argument type!"_ustr,
571 getXWeak(),
572 -1 ) ),
573 Environment );
574 // Unreachable
577 aRet <<= createNewContent( aInfo );
579 else if ( aCommand.Name == "flush" )
582 // flush
583 // ( Not available at stream objects )
586 if( !flushData() )
588 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
590 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
591 }));
592 ucbhelper::cancelCommandExecution(
593 ucb::IOErrorCode_CANT_WRITE,
594 aArgs,
595 Environment,
596 u"Cannot write file to disk!"_ustr,
597 this );
598 // Unreachable
601 else
604 // Unsupported command
607 ucbhelper::cancelCommandExecution(
608 uno::Any( ucb::UnsupportedCommandException(
609 OUString(),
610 getXWeak() ) ),
611 Environment );
612 // Unreachable
615 return aRet;
619 // virtual
620 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
622 // @@@ Implement logic to abort running commands, if this makes
623 // sense for your content.
627 // XContentCreator methods.
630 // virtual
631 uno::Sequence< ucb::ContentInfo > SAL_CALL
632 Content::queryCreatableContentsInfo()
634 return m_aProps.getCreatableContentsInfo( m_aUri );
638 // virtual
639 uno::Reference< ucb::XContent > SAL_CALL
640 Content::createNewContent( const ucb::ContentInfo& Info )
642 if ( isFolder() )
644 osl::Guard< osl::Mutex > aGuard( m_aMutex );
646 if ( Info.Type.isEmpty() )
647 return uno::Reference< ucb::XContent >();
649 if ( !Info.Type.equalsIgnoreAsciiCase(
650 getContentType( m_aUri.getScheme(), true ) ) &&
651 !Info.Type.equalsIgnoreAsciiCase(
652 getContentType( m_aUri.getScheme(), false ) ) )
653 return uno::Reference< ucb::XContent >();
655 OUString aURL = m_aUri.getUri() + "/";
657 if ( Info.Type.equalsIgnoreAsciiCase(
658 getContentType( m_aUri.getScheme(), true ) ) )
659 aURL += "New_Folder";
660 else
661 aURL += "New_Stream";
663 uno::Reference< ucb::XContentIdentifier > xId(
664 new ::ucbhelper::ContentIdentifier( aURL ) );
666 return create( m_xContext, m_pProvider, xId, Info );
668 else
670 OSL_FAIL( "createNewContent called on non-folder object!" );
671 return uno::Reference< ucb::XContent >();
676 // Non-interface methods.
679 // virtual
680 OUString Content::getParentURL()
682 return m_aUri.getParentUri();
686 // static
687 uno::Reference< sdbc::XRow > Content::getPropertyValues(
688 const uno::Reference< uno::XComponentContext >& rxContext,
689 const uno::Sequence< beans::Property >& rProperties,
690 ContentProvider* pProvider,
691 const OUString& rContentId )
693 ContentProperties aData;
694 uno::Reference< container::XHierarchicalNameAccess > xPackage;
695 if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) )
697 return getPropertyValues( rxContext,
698 rProperties,
699 aData,
700 rtl::Reference<
701 ::ucbhelper::ContentProviderImplHelper >(
702 pProvider ),
703 rContentId );
705 else
707 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
708 = new ::ucbhelper::PropertyValueSet( rxContext );
710 for ( const beans::Property& rProp : rProperties )
711 xRow->appendVoid( rProp );
713 return xRow;
718 // static
719 uno::Reference< sdbc::XRow > Content::getPropertyValues(
720 const uno::Reference< uno::XComponentContext >& rxContext,
721 const uno::Sequence< beans::Property >& rProperties,
722 const ContentProperties& rData,
723 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >&
724 rProvider,
725 const OUString& rContentId )
727 // Note: Empty sequence means "get values of all supported properties".
729 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
730 = new ::ucbhelper::PropertyValueSet( rxContext );
732 if ( rProperties.hasElements() )
734 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
735 bool bTriedToGetAdditionalPropSet = false;
737 for ( const beans::Property& rProp : rProperties )
739 // Process Core properties.
741 if ( rProp.Name == "ContentType" )
743 xRow->appendString ( rProp, rData.aContentType );
745 else if ( rProp.Name == "Title" )
747 xRow->appendString ( rProp, rData.aTitle );
749 else if ( rProp.Name == "IsDocument" )
751 xRow->appendBoolean( rProp, rData.bIsDocument );
753 else if ( rProp.Name == "IsFolder" )
755 xRow->appendBoolean( rProp, rData.bIsFolder );
757 else if ( rProp.Name == "CreatableContentsInfo" )
759 xRow->appendObject(
760 rProp, uno::Any(
761 rData.getCreatableContentsInfo(
762 PackageUri( rContentId ) ) ) );
764 else if ( rProp.Name == "MediaType" )
766 xRow->appendString ( rProp, rData.aMediaType );
768 else if ( rProp.Name == "Size" )
770 // Property only available for streams.
771 if ( rData.bIsDocument )
772 xRow->appendLong( rProp, rData.nSize );
773 else
774 xRow->appendVoid( rProp );
776 else if ( rProp.Name == "Compressed" )
778 // Property only available for streams.
779 if ( rData.bIsDocument )
780 xRow->appendBoolean( rProp, rData.bCompressed );
781 else
782 xRow->appendVoid( rProp );
784 else if ( rProp.Name == "Encrypted" )
786 // Property only available for streams.
787 if ( rData.bIsDocument )
788 xRow->appendBoolean( rProp, rData.bEncrypted );
789 else
790 xRow->appendVoid( rProp );
792 else if ( rProp.Name == "HasEncryptedEntries" )
794 // Property only available for root folder.
795 PackageUri aURI( rContentId );
796 if ( aURI.isRootFolder() )
797 xRow->appendBoolean( rProp, rData.bHasEncryptedEntries );
798 else
799 xRow->appendVoid( rProp );
801 else
803 // Not a Core Property! Maybe it's an Additional Core Property?!
805 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
807 xAdditionalPropSet =
808 rProvider->getAdditionalPropertySet( rContentId,
809 false );
810 bTriedToGetAdditionalPropSet = true;
813 if ( xAdditionalPropSet.is() )
815 if ( !xRow->appendPropertySetValue(
816 xAdditionalPropSet,
817 rProp ) )
819 // Append empty entry.
820 xRow->appendVoid( rProp );
823 else
825 // Append empty entry.
826 xRow->appendVoid( rProp );
831 else
833 // Append all Core Properties.
834 xRow->appendString (
835 beans::Property(
836 u"ContentType"_ustr,
838 cppu::UnoType<OUString>::get(),
839 beans::PropertyAttribute::BOUND
840 | beans::PropertyAttribute::READONLY ),
841 rData.aContentType );
842 xRow->appendString(
843 beans::Property(
844 u"Title"_ustr,
846 cppu::UnoType<OUString>::get(),
847 beans::PropertyAttribute::BOUND ),
848 rData.aTitle );
849 xRow->appendBoolean(
850 beans::Property(
851 u"IsDocument"_ustr,
853 cppu::UnoType<bool>::get(),
854 beans::PropertyAttribute::BOUND
855 | beans::PropertyAttribute::READONLY ),
856 rData.bIsDocument );
857 xRow->appendBoolean(
858 beans::Property(
859 u"IsFolder"_ustr,
861 cppu::UnoType<bool>::get(),
862 beans::PropertyAttribute::BOUND
863 | beans::PropertyAttribute::READONLY ),
864 rData.bIsFolder );
865 xRow->appendObject(
866 beans::Property(
867 u"CreatableContentsInfo"_ustr,
869 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
870 beans::PropertyAttribute::BOUND
871 | beans::PropertyAttribute::READONLY ),
872 uno::Any(
873 rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
874 xRow->appendString(
875 beans::Property(
876 u"MediaType"_ustr,
878 cppu::UnoType<OUString>::get(),
879 beans::PropertyAttribute::BOUND ),
880 rData.aMediaType );
882 // Properties only available for streams.
883 if ( rData.bIsDocument )
885 xRow->appendLong(
886 beans::Property(
887 u"Size"_ustr,
889 cppu::UnoType<sal_Int64>::get(),
890 beans::PropertyAttribute::BOUND
891 | beans::PropertyAttribute::READONLY ),
892 rData.nSize );
894 xRow->appendBoolean(
895 beans::Property(
896 u"Compressed"_ustr,
898 cppu::UnoType<bool>::get(),
899 beans::PropertyAttribute::BOUND ),
900 rData.bCompressed );
902 xRow->appendBoolean(
903 beans::Property(
904 u"Encrypted"_ustr,
906 cppu::UnoType<bool>::get(),
907 beans::PropertyAttribute::BOUND ),
908 rData.bEncrypted );
911 // Properties only available for root folder.
912 PackageUri aURI( rContentId );
913 if ( aURI.isRootFolder() )
915 xRow->appendBoolean(
916 beans::Property(
917 u"HasEncryptedEntries"_ustr,
919 cppu::UnoType<bool>::get(),
920 beans::PropertyAttribute::BOUND
921 | beans::PropertyAttribute::READONLY ),
922 rData.bHasEncryptedEntries );
925 // Append all Additional Core Properties.
927 uno::Reference< beans::XPropertySet > xSet =
928 rProvider->getAdditionalPropertySet( rContentId, false );
929 xRow->appendPropertySet( xSet );
932 return xRow;
936 uno::Reference< sdbc::XRow > Content::getPropertyValues(
937 const uno::Sequence< beans::Property >& rProperties )
939 osl::Guard< osl::Mutex > aGuard( m_aMutex );
940 return getPropertyValues( m_xContext,
941 rProperties,
942 m_aProps,
943 m_xProvider,
944 m_xIdentifier->getContentIdentifier() );
948 uno::Sequence< uno::Any > Content::setPropertyValues(
949 const uno::Sequence< beans::PropertyValue >& rValues,
950 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
952 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
954 uno::Sequence< uno::Any > aRet( rValues.getLength() );
955 auto aRetRange = asNonConstRange(aRet);
956 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
957 sal_Int32 nChanged = 0;
959 beans::PropertyChangeEvent aEvent;
960 aEvent.Source = getXWeak();
961 aEvent.Further = false;
962 // aEvent.PropertyName =
963 aEvent.PropertyHandle = -1;
964 // aEvent.OldValue =
965 // aEvent.NewValue =
967 const beans::PropertyValue* pValues = rValues.getConstArray();
968 sal_Int32 nCount = rValues.getLength();
970 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
971 bool bTriedToGetAdditionalPropSet = false;
972 bool bExchange = false;
973 bool bStore = false;
974 OUString aNewTitle;
975 sal_Int32 nTitlePos = -1;
977 for ( sal_Int32 n = 0; n < nCount; ++n )
979 const beans::PropertyValue& rValue = pValues[ n ];
981 if ( rValue.Name == "ContentType" )
983 // Read-only property!
984 aRetRange[ n ] <<= lang::IllegalAccessException(
985 u"Property is read-only!"_ustr,
986 getXWeak() );
988 else if ( rValue.Name == "IsDocument" )
990 // Read-only property!
991 aRetRange[ n ] <<= lang::IllegalAccessException(
992 u"Property is read-only!"_ustr,
993 getXWeak() );
995 else if ( rValue.Name == "IsFolder" )
997 // Read-only property!
998 aRetRange[ n ] <<= lang::IllegalAccessException(
999 u"Property is read-only!"_ustr,
1000 getXWeak() );
1002 else if ( rValue.Name == "CreatableContentsInfo" )
1004 // Read-only property!
1005 aRetRange[ n ] <<= lang::IllegalAccessException(
1006 u"Property is read-only!"_ustr,
1007 getXWeak() );
1009 else if ( rValue.Name == "Title" )
1011 if ( m_aUri.isRootFolder() )
1013 // Read-only property!
1014 aRetRange[ n ] <<= lang::IllegalAccessException(
1015 u"Property is read-only!"_ustr,
1016 getXWeak() );
1018 else
1020 OUString aNewValue;
1021 if ( rValue.Value >>= aNewValue )
1023 // No empty titles!
1024 if ( !aNewValue.isEmpty() )
1026 if ( aNewValue != m_aProps.aTitle )
1028 // modified title -> modified URL -> exchange !
1029 if ( m_eState == PERSISTENT )
1030 bExchange = true;
1032 // new value will be set later...
1033 aNewTitle = aNewValue;
1035 // remember position within sequence of values
1036 // (for error handling).
1037 nTitlePos = n;
1040 else
1042 aRetRange[ n ] <<=
1043 lang::IllegalArgumentException(
1044 u"Empty title not allowed!"_ustr,
1045 getXWeak(),
1046 -1 );
1049 else
1051 aRetRange[ n ] <<=
1052 beans::IllegalTypeException(
1053 u"Property value has wrong type!"_ustr,
1054 getXWeak() );
1058 else if ( rValue.Name == "MediaType" )
1060 OUString aNewValue;
1061 if ( rValue.Value >>= aNewValue )
1063 if ( aNewValue != m_aProps.aMediaType )
1065 aEvent.PropertyName = rValue.Name;
1066 aEvent.OldValue <<= m_aProps.aMediaType;
1067 aEvent.NewValue <<= aNewValue;
1069 m_aProps.aMediaType = aNewValue;
1070 nChanged++;
1071 bStore = true;
1072 m_nModifiedProps |= MEDIATYPE_MODIFIED;
1075 else
1077 aRetRange[ n ] <<= beans::IllegalTypeException(
1078 u"Property value has wrong type!"_ustr,
1079 getXWeak() );
1082 else if ( rValue.Name == "Size" )
1084 // Read-only property!
1085 aRetRange[ n ] <<= lang::IllegalAccessException(
1086 u"Property is read-only!"_ustr,
1087 getXWeak() );
1089 else if ( rValue.Name == "Compressed" )
1091 // Property only available for streams.
1092 if ( m_aProps.bIsDocument )
1094 bool bNewValue;
1095 if ( rValue.Value >>= bNewValue )
1097 if ( bNewValue != m_aProps.bCompressed )
1099 aEvent.PropertyName = rValue.Name;
1100 aEvent.OldValue <<= m_aProps.bCompressed;
1101 aEvent.NewValue <<= bNewValue;
1103 m_aProps.bCompressed = bNewValue;
1104 nChanged++;
1105 bStore = true;
1106 m_nModifiedProps |= COMPRESSED_MODIFIED;
1109 else
1111 aRetRange[ n ] <<= beans::IllegalTypeException(
1112 u"Property value has wrong type!"_ustr,
1113 getXWeak() );
1116 else
1118 aRetRange[ n ] <<= beans::UnknownPropertyException(
1119 u"Compressed only supported by streams!"_ustr,
1120 getXWeak() );
1123 else if ( rValue.Name == "Encrypted" )
1125 // Property only available for streams.
1126 if ( m_aProps.bIsDocument )
1128 bool bNewValue;
1129 if ( rValue.Value >>= bNewValue )
1131 if ( bNewValue != m_aProps.bEncrypted )
1133 aEvent.PropertyName = rValue.Name;
1134 aEvent.OldValue <<= m_aProps.bEncrypted;
1135 aEvent.NewValue <<= bNewValue;
1137 m_aProps.bEncrypted = bNewValue;
1138 nChanged++;
1139 bStore = true;
1140 m_nModifiedProps |= ENCRYPTED_MODIFIED;
1143 else
1145 aRetRange[ n ] <<= beans::IllegalTypeException(
1146 u"Property value has wrong type!"_ustr,
1147 getXWeak() );
1150 else
1152 aRetRange[ n ] <<= beans::UnknownPropertyException(
1153 u"Encrypted only supported by streams!"_ustr,
1154 getXWeak() );
1157 else if ( rValue.Name == "HasEncryptedEntries" )
1159 // Read-only property!
1160 aRetRange[ n ] <<= lang::IllegalAccessException(
1161 u"Property is read-only!"_ustr,
1162 getXWeak() );
1164 else if ( rValue.Name == "EncryptionKey" )
1166 // @@@ This is a temporary solution. In the future submitting
1167 // the key should be done using an interaction handler!
1169 // Write-Only property. Only supported by root folder and streams
1170 // (all non-root folders of a package have the same encryption key).
1171 if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
1173 uno::Sequence < sal_Int8 > aNewValue;
1174 if ( rValue.Value >>= aNewValue )
1176 if ( aNewValue != m_aProps.aEncryptionKey )
1178 aEvent.PropertyName = rValue.Name;
1179 aEvent.OldValue <<= m_aProps.aEncryptionKey;
1180 aEvent.NewValue <<= aNewValue;
1182 m_aProps.aEncryptionKey = std::move(aNewValue);
1183 nChanged++;
1184 bStore = true;
1185 m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
1188 else
1190 aRetRange[ n ] <<= beans::IllegalTypeException(
1191 u"Property value has wrong type!"_ustr,
1192 getXWeak() );
1195 else
1197 aRetRange[ n ] <<= beans::UnknownPropertyException(
1198 u"EncryptionKey not supported by non-root folder!"_ustr,
1199 getXWeak() );
1202 else
1204 // Not a Core Property! Maybe it's an Additional Core Property?!
1206 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1208 xAdditionalPropSet = getAdditionalPropertySet( false );
1209 bTriedToGetAdditionalPropSet = true;
1212 if ( xAdditionalPropSet.is() )
1216 uno::Any aOldValue
1217 = xAdditionalPropSet->getPropertyValue( rValue.Name );
1218 if ( aOldValue != rValue.Value )
1220 xAdditionalPropSet->setPropertyValue(
1221 rValue.Name, rValue.Value );
1223 aEvent.PropertyName = rValue.Name;
1224 aEvent.OldValue = std::move(aOldValue);
1225 aEvent.NewValue = rValue.Value;
1227 aChanges.getArray()[ nChanged ] = aEvent;
1228 nChanged++;
1231 catch ( beans::UnknownPropertyException const & e )
1233 aRetRange[ n ] <<= e;
1235 catch ( lang::WrappedTargetException const & e )
1237 aRetRange[ n ] <<= e;
1239 catch ( beans::PropertyVetoException const & e )
1241 aRetRange[ n ] <<= e;
1243 catch ( lang::IllegalArgumentException const & e )
1245 aRetRange[ n ] <<= e;
1248 else
1250 aRetRange[ n ] <<= uno::Exception(
1251 u"No property set for storing the value!"_ustr,
1252 getXWeak() );
1257 if ( bExchange )
1259 uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
1261 // Assemble new content identifier...
1262 OUString aNewURL = m_aUri.getParentUri() + "/" +
1263 ::ucb_impl::urihelper::encodeSegment( aNewTitle );
1264 uno::Reference< ucb::XContentIdentifier > xNewId
1265 = new ::ucbhelper::ContentIdentifier( aNewURL );
1267 aGuard.clear();
1268 if ( exchangeIdentity( xNewId ) )
1270 // Adapt persistent data.
1271 renameData( xOldId, xNewId );
1273 // Adapt Additional Core Properties.
1274 renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1275 xNewId->getContentIdentifier() );
1277 else
1279 // Do not set new title!
1280 aNewTitle.clear();
1282 // Set error .
1283 aRetRange[ nTitlePos ] <<= uno::Exception(
1284 u"Exchange failed!"_ustr,
1285 getXWeak() );
1289 if ( !aNewTitle.isEmpty() )
1291 aEvent.PropertyName = "Title";
1292 aEvent.OldValue <<= m_aProps.aTitle;
1293 aEvent.NewValue <<= aNewTitle;
1295 m_aProps.aTitle = aNewTitle;
1297 aChanges.getArray()[ nChanged ] = std::move(aEvent);
1298 nChanged++;
1301 if ( nChanged > 0 )
1303 // Save changes, if content was already made persistent.
1304 if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
1305 ( bStore && ( m_eState == PERSISTENT ) ) )
1307 if ( !storeData( uno::Reference< io::XInputStream >() ) )
1309 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1311 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1312 }));
1313 ucbhelper::cancelCommandExecution(
1314 ucb::IOErrorCode_CANT_WRITE,
1315 aArgs,
1316 xEnv,
1317 u"Cannot store persistent data!"_ustr,
1318 this );
1319 // Unreachable
1323 aGuard.clear();
1324 aChanges.realloc( nChanged );
1325 notifyPropertiesChange( aChanges );
1328 return aRet;
1332 uno::Any Content::open(
1333 const ucb::OpenCommandArgument2& rArg,
1334 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1336 if ( rArg.Mode == ucb::OpenMode::ALL ||
1337 rArg.Mode == ucb::OpenMode::FOLDERS ||
1338 rArg.Mode == ucb::OpenMode::DOCUMENTS )
1341 // open command for a folder content
1344 uno::Reference< ucb::XDynamicResultSet > xSet
1345 = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1346 return uno::Any( xSet );
1348 else
1351 // open command for a document content
1354 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1355 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1357 // Currently(?) unsupported.
1358 ucbhelper::cancelCommandExecution(
1359 uno::Any( ucb::UnsupportedOpenModeException(
1360 OUString(),
1361 getXWeak(),
1362 sal_Int16( rArg.Mode ) ) ),
1363 xEnv );
1364 // Unreachable
1367 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1368 if ( xOut.is() )
1370 // PUSH: write data into xOut
1372 uno::Reference< io::XInputStream > xIn = getInputStream();
1373 if ( !xIn.is() )
1375 // No interaction if we are not persistent!
1376 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1378 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1379 }));
1380 ucbhelper::cancelCommandExecution(
1381 ucb::IOErrorCode_CANT_READ,
1382 aArgs,
1383 m_eState == PERSISTENT
1384 ? xEnv
1385 : uno::Reference< ucb::XCommandEnvironment >(),
1386 u"Got no data stream!"_ustr,
1387 this );
1388 // Unreachable
1393 uno::Sequence< sal_Int8 > aBuffer;
1394 while (true)
1396 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1397 if (!nRead)
1398 break;
1399 aBuffer.realloc( nRead );
1400 xOut->writeBytes( aBuffer );
1403 xOut->closeOutput();
1405 catch ( io::NotConnectedException const & )
1407 // closeOutput, readSomeBytes, writeBytes
1409 catch ( io::BufferSizeExceededException const & )
1411 // closeOutput, readSomeBytes, writeBytes
1413 catch ( io::IOException const & )
1415 // closeOutput, readSomeBytes, writeBytes
1418 else
1420 uno::Reference< io::XActiveDataSink > xDataSink(
1421 rArg.Sink, uno::UNO_QUERY );
1422 if ( xDataSink.is() )
1424 // PULL: wait for client read
1426 uno::Reference< io::XInputStream > xIn = getInputStream();
1427 if ( !xIn.is() )
1429 // No interaction if we are not persistent!
1430 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1432 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1433 }));
1434 ucbhelper::cancelCommandExecution(
1435 ucb::IOErrorCode_CANT_READ,
1436 aArgs,
1437 m_eState == PERSISTENT
1438 ? xEnv
1439 : uno::Reference<
1440 ucb::XCommandEnvironment >(),
1441 u"Got no data stream!"_ustr,
1442 this );
1443 // Unreachable
1446 // Done.
1447 xDataSink->setInputStream( xIn );
1449 else
1451 // Note: aOpenCommand.Sink may contain an XStream
1452 // implementation. Support for this type of
1453 // sink is optional...
1454 ucbhelper::cancelCommandExecution(
1455 uno::Any(
1456 ucb::UnsupportedDataSinkException(
1457 OUString(),
1458 getXWeak(),
1459 rArg.Sink ) ),
1460 xEnv );
1461 // Unreachable
1466 return uno::Any();
1470 void Content::insert(
1471 const uno::Reference< io::XInputStream >& xStream,
1472 sal_Int32 nNameClashResolve,
1473 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1475 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1477 // Check, if all required properties were set.
1478 if ( isFolder() )
1480 // Required: Title
1482 if ( m_aProps.aTitle.isEmpty() )
1483 m_aProps.aTitle = m_aUri.getName();
1485 else
1487 // Required: rArg.Data
1489 if ( !xStream.is() )
1491 ucbhelper::cancelCommandExecution(
1492 uno::Any( ucb::MissingInputStreamException(
1493 OUString(),
1494 getXWeak() ) ),
1495 xEnv );
1496 // Unreachable
1499 // Required: Title
1501 if ( m_aProps.aTitle.isEmpty() )
1502 m_aProps.aTitle = m_aUri.getName();
1505 OUString aNewURL = m_aUri.getParentUri();
1506 if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
1507 aNewURL += "/";
1508 aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
1509 PackageUri aNewUri( aNewURL );
1511 // Handle possible name clash...
1512 switch ( nNameClashResolve )
1514 // fail.
1515 case ucb::NameClash::ERROR:
1516 if ( hasData( aNewUri ) )
1518 ucbhelper::cancelCommandExecution(
1519 uno::Any( ucb::NameClashException(
1520 OUString(),
1521 getXWeak(),
1522 task::InteractionClassification_ERROR,
1523 m_aProps.aTitle ) ),
1524 xEnv );
1525 // Unreachable
1527 break;
1529 // replace (possibly) existing object.
1530 case ucb::NameClash::OVERWRITE:
1531 break;
1533 // "invent" a new valid title.
1534 case ucb::NameClash::RENAME:
1535 if ( hasData( aNewUri ) )
1537 sal_Int32 nTry = 0;
1541 OUString aNew = aNewUri.getUri() + "_" + OUString::number( ++nTry );
1542 aNewUri.setUri( aNew );
1544 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1546 if ( nTry == 1000 )
1548 ucbhelper::cancelCommandExecution(
1549 uno::Any(
1550 ucb::UnsupportedNameClashException(
1551 u"Unable to resolve name clash!"_ustr,
1552 getXWeak(),
1553 nNameClashResolve ) ),
1554 xEnv );
1555 // Unreachable
1557 else
1559 m_aProps.aTitle += "_";
1560 m_aProps.aTitle += OUString::number( nTry );
1563 break;
1565 case ucb::NameClash::KEEP: // deprecated
1566 case ucb::NameClash::ASK:
1567 default:
1568 if ( hasData( aNewUri ) )
1570 ucbhelper::cancelCommandExecution(
1571 uno::Any(
1572 ucb::UnsupportedNameClashException(
1573 OUString(),
1574 getXWeak(),
1575 nNameClashResolve ) ),
1576 xEnv );
1577 // Unreachable
1579 break;
1582 // Identifier changed?
1583 bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
1585 if ( bNewId )
1587 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1588 m_aUri = std::move(aNewUri);
1591 if ( !storeData( xStream ) )
1593 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1595 {"Uri", uno::Any(m_xIdentifier->getContentIdentifier())}
1596 }));
1597 ucbhelper::cancelCommandExecution(
1598 ucb::IOErrorCode_CANT_WRITE,
1599 aArgs,
1600 xEnv,
1601 u"Cannot store persistent data!"_ustr,
1602 this );
1603 // Unreachable
1606 m_eState = PERSISTENT;
1608 if ( bNewId )
1610 // Take over correct default values from underlying packager...
1611 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1612 loadData( m_pProvider,
1613 m_aUri,
1614 m_aProps,
1615 xXHierarchicalNameAccess );
1617 aGuard.clear();
1618 inserted();
1623 void Content::destroy(
1624 bool bDeletePhysical,
1625 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1627 // @@@ take care about bDeletePhysical -> trashcan support
1629 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1631 uno::Reference< ucb::XContent > xThis = this;
1633 // Persistent?
1634 if ( m_eState != PERSISTENT )
1636 ucbhelper::cancelCommandExecution(
1637 uno::Any( ucb::UnsupportedCommandException(
1638 u"Not persistent!"_ustr,
1639 getXWeak() ) ),
1640 xEnv );
1641 // Unreachable
1644 m_eState = DEAD;
1646 aGuard.clear();
1647 deleted();
1649 if ( isFolder() )
1651 // Process instantiated children...
1653 ContentRefList aChildren;
1654 queryChildren( aChildren );
1656 for ( auto& rChild : aChildren )
1658 rChild->destroy( bDeletePhysical, xEnv );
1664 void Content::transfer(
1665 const ucb::TransferInfo& rInfo,
1666 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1668 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1670 // Persistent?
1671 if ( m_eState != PERSISTENT )
1673 ucbhelper::cancelCommandExecution(
1674 uno::Any( ucb::UnsupportedCommandException(
1675 u"Not persistent!"_ustr,
1676 getXWeak() ) ),
1677 xEnv );
1678 // Unreachable
1681 // Is source a package content?
1682 if ( ( rInfo.SourceURL.isEmpty() ) ||
1683 ( rInfo.SourceURL.compareTo(
1684 m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
1686 ucbhelper::cancelCommandExecution(
1687 uno::Any( ucb::InteractiveBadTransferURLException(
1688 OUString(),
1689 getXWeak() ) ),
1690 xEnv );
1691 // Unreachable
1694 // Is source not a parent of me / not me?
1695 OUString aId = m_aUri.getParentUri() + "/";
1697 if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1699 if ( aId.startsWith( rInfo.SourceURL ) )
1701 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1703 {"Uri", uno::Any(rInfo.SourceURL)}
1704 }));
1705 ucbhelper::cancelCommandExecution(
1706 ucb::IOErrorCode_RECURSIVE,
1707 aArgs,
1708 xEnv,
1709 u"Target is equal to or is a child of source!"_ustr,
1710 this );
1711 // Unreachable
1716 // 0) Obtain content object for source.
1719 uno::Reference< ucb::XContentIdentifier > xId
1720 = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1722 // Note: The static cast is okay here, because its sure that
1723 // m_xProvider is always the PackageContentProvider.
1724 rtl::Reference< Content > xSource;
1728 xSource = static_cast< Content * >(
1729 m_xProvider->queryContent( xId ).get() );
1731 catch ( ucb::IllegalIdentifierException const & )
1733 // queryContent
1736 if ( !xSource.is() )
1738 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1740 {"Uri", uno::Any(xId->getContentIdentifier())}
1741 }));
1742 ucbhelper::cancelCommandExecution(
1743 ucb::IOErrorCode_CANT_READ,
1744 aArgs,
1745 xEnv,
1746 u"Cannot instantiate source object!"_ustr,
1747 this );
1748 // Unreachable
1752 // 1) Create new child content.
1755 ucb::ContentInfo aContentInfo;
1756 aContentInfo.Type = xSource->isFolder()
1757 ? getContentType( m_aUri.getScheme(), true )
1758 : getContentType( m_aUri.getScheme(), false );
1759 aContentInfo.Attributes = 0;
1761 // Note: The static cast is okay here, because its sure that
1762 // createNewContent always creates a Content.
1763 rtl::Reference< Content > xTarget
1764 = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1765 if ( !xTarget.is() )
1767 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1769 {"Folder", uno::Any(aId)}
1770 }));
1771 ucbhelper::cancelCommandExecution(
1772 ucb::IOErrorCode_CANT_CREATE,
1773 aArgs,
1774 xEnv,
1775 u"XContentCreator::createNewContent failed!"_ustr,
1776 this );
1777 // Unreachable
1781 // 2) Copy data from source content to child content.
1784 uno::Sequence< beans::Property > aSourceProps
1785 = xSource->getPropertySetInfo( xEnv )->getProperties();
1786 sal_Int32 nCount = aSourceProps.getLength();
1788 if ( nCount )
1790 bool bHadTitle = rInfo.NewTitle.isEmpty();
1792 // Get all source values.
1793 uno::Reference< sdbc::XRow > xRow
1794 = xSource->getPropertyValues( aSourceProps );
1796 uno::Sequence< beans::PropertyValue > aValues( nCount );
1797 beans::PropertyValue* pValues = aValues.getArray();
1799 const beans::Property* pProps = aSourceProps.getConstArray();
1800 for ( sal_Int32 n = 0; n < nCount; ++n )
1802 const beans::Property& rProp = pProps[ n ];
1803 beans::PropertyValue& rValue = pValues[ n ];
1805 rValue.Name = rProp.Name;
1806 rValue.Handle = rProp.Handle;
1808 if ( !bHadTitle && rProp.Name == "Title" )
1810 // Set new title instead of original.
1811 bHadTitle = true;
1812 rValue.Value <<= rInfo.NewTitle;
1814 else
1815 rValue.Value
1816 = xRow->getObject( n + 1,
1817 uno::Reference<
1818 container::XNameAccess >() );
1820 rValue.State = beans::PropertyState_DIRECT_VALUE;
1822 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1824 // Add Additional Core Property.
1827 xTarget->addProperty( rProp.Name,
1828 rProp.Attributes,
1829 rValue.Value );
1831 catch ( beans::PropertyExistException const & )
1834 catch ( beans::IllegalTypeException const & )
1837 catch ( lang::IllegalArgumentException const & )
1843 // Set target values.
1844 xTarget->setPropertyValues( aValues, xEnv );
1848 // 3) Commit (insert) child.
1851 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
1854 // 4) Transfer (copy) children of source.
1857 if ( xSource->isFolder() )
1859 uno::Reference< container::XEnumeration > xIter
1860 = xSource->getIterator();
1861 if ( xIter.is() )
1863 while ( xIter->hasMoreElements() )
1867 uno::Reference< container::XNamed > xNamed;
1868 xIter->nextElement() >>= xNamed;
1870 if ( !xNamed.is() )
1872 OSL_FAIL( "Content::transfer - Got no XNamed!" );
1873 break;
1876 OUString aName = xNamed->getName();
1878 if ( aName.isEmpty() )
1880 OSL_FAIL( "Content::transfer - Empty name!" );
1881 break;
1884 OUString aChildId = xId->getContentIdentifier();
1885 if ( ( aChildId.lastIndexOf( '/' ) + 1 )
1886 != aChildId.getLength() )
1887 aChildId += "/";
1889 aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
1891 ucb::TransferInfo aInfo;
1892 aInfo.MoveData = false;
1893 aInfo.NewTitle.clear();
1894 aInfo.SourceURL = aChildId;
1895 aInfo.NameClash = rInfo.NameClash;
1897 // Transfer child to target.
1898 xTarget->transfer( aInfo, xEnv );
1900 catch ( container::NoSuchElementException const & )
1903 catch ( lang::WrappedTargetException const & )
1911 // 5) Destroy source ( when moving only ) .
1914 if ( !rInfo.MoveData )
1915 return;
1917 xSource->destroy( true, xEnv );
1919 // Remove all persistent data of source and its children.
1920 if ( !xSource->removeData() )
1922 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1924 {"Uri", uno::Any(xSource->m_xIdentifier->getContentIdentifier())}
1925 }));
1926 ucbhelper::cancelCommandExecution(
1927 ucb::IOErrorCode_CANT_WRITE,
1928 aArgs,
1929 xEnv,
1930 u"Cannot remove persistent data of source object!"_ustr,
1931 this );
1932 // Unreachable
1935 // Remove own and all children's Additional Core Properties.
1936 xSource->removeAdditionalPropertySet();
1940 bool Content::exchangeIdentity(
1941 const uno::Reference< ucb::XContentIdentifier >& xNewId )
1943 if ( !xNewId.is() )
1944 return false;
1946 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1948 uno::Reference< ucb::XContent > xThis = this;
1950 // Already persistent?
1951 if ( m_eState != PERSISTENT )
1953 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
1954 return false;
1957 // Exchange own identity.
1959 // Fail, if a content with given id already exists.
1960 PackageUri aNewUri( xNewId->getContentIdentifier() );
1961 if ( !hasData( aNewUri ) )
1963 OUString aOldURL = m_xIdentifier->getContentIdentifier();
1965 aGuard.clear();
1966 if ( exchange( xNewId ) )
1968 m_aUri = std::move(aNewUri);
1969 if ( isFolder() )
1971 // Process instantiated children...
1973 ContentRefList aChildren;
1974 queryChildren( aChildren );
1976 for ( const auto& rChild : aChildren )
1978 ContentRef xChild = rChild;
1980 // Create new content identifier for the child...
1981 uno::Reference< ucb::XContentIdentifier > xOldChildId
1982 = xChild->getIdentifier();
1983 OUString aOldChildURL
1984 = xOldChildId->getContentIdentifier();
1985 OUString aNewChildURL
1986 = aOldChildURL.replaceAt(
1988 aOldURL.getLength(),
1989 xNewId->getContentIdentifier() );
1990 uno::Reference< ucb::XContentIdentifier > xNewChildId
1991 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
1993 if ( !xChild->exchangeIdentity( xNewChildId ) )
1994 return false;
1997 return true;
2001 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2002 return false;
2006 void Content::queryChildren( ContentRefList& rChildren )
2008 // Obtain a list with a snapshot of all currently instantiated contents
2009 // from provider and extract the contents which are direct children
2010 // of this content.
2012 ::ucbhelper::ContentRefList aAllContents;
2013 m_xProvider->queryExistingContents( aAllContents );
2015 OUString aURL = m_xIdentifier->getContentIdentifier();
2017 OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2018 "Content::queryChildren - Invalid URL!" );
2020 aURL += "/";
2022 sal_Int32 nLen = aURL.getLength();
2024 for ( const auto& rContent : aAllContents )
2026 ::ucbhelper::ContentImplHelperRef xChild = rContent;
2027 OUString aChildURL
2028 = xChild->getIdentifier()->getContentIdentifier();
2030 // Is aURL a prefix of aChildURL?
2031 if ( ( aChildURL.getLength() > nLen ) &&
2032 ( aChildURL.startsWith( aURL ) ) )
2034 if ( aChildURL.indexOf( '/', nLen ) == -1 )
2036 // No further slashes. It's a child!
2037 rChildren.emplace_back(
2038 static_cast< Content * >( xChild.get() ) );
2045 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2046 const PackageUri& rURI )
2048 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2050 if ( rURI.getPackage() == m_aUri.getPackage() )
2052 if ( !m_xPackage.is() )
2053 m_xPackage = m_pProvider->createPackage( m_aUri );
2055 return m_xPackage;
2058 return m_pProvider->createPackage( rURI );
2062 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2064 return getPackage( m_aUri );
2068 // static
2069 bool Content::hasData(
2070 ContentProvider* pProvider,
2071 const PackageUri& rURI,
2072 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2074 rxPackage = pProvider->createPackage( rURI );
2075 return rxPackage->hasByHierarchicalName( rURI.getPath() );
2079 bool Content::hasData( const PackageUri& rURI )
2081 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2083 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2084 if ( rURI.getPackage() == m_aUri.getPackage() )
2086 xPackage = getPackage();
2087 return xPackage->hasByHierarchicalName( rURI.getPath() );
2090 return hasData( m_pProvider, rURI, xPackage );
2094 //static
2095 bool Content::loadData(
2096 ContentProvider* pProvider,
2097 const PackageUri& rURI,
2098 ContentProperties& rProps,
2099 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2101 rxPackage = pProvider->createPackage( rURI );
2103 if ( rURI.isRootFolder() )
2105 // Properties available only from package
2106 uno::Reference< beans::XPropertySet > xPackagePropSet(
2107 rxPackage, uno::UNO_QUERY );
2109 OSL_ENSURE( xPackagePropSet.is(),
2110 "Content::loadData - "
2111 "Got no XPropertySet interface from package!" );
2113 if ( xPackagePropSet.is() )
2115 // HasEncryptedEntries (only available at root folder)
2118 uno::Any aHasEncryptedEntries
2119 = xPackagePropSet->getPropertyValue( u"HasEncryptedEntries"_ustr );
2120 if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2122 OSL_FAIL( "Content::loadData - "
2123 "Got no HasEncryptedEntries value!" );
2124 return false;
2127 catch ( beans::UnknownPropertyException const & )
2129 OSL_FAIL( "Content::loadData - "
2130 "Got no HasEncryptedEntries value!" );
2131 return false;
2133 catch ( lang::WrappedTargetException const & )
2135 OSL_FAIL( "Content::loadData - "
2136 "Got no HasEncryptedEntries value!" );
2137 return false;
2142 if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2143 return false;
2147 uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2148 if ( aEntry.hasValue() )
2150 uno::Reference< beans::XPropertySet > xPropSet;
2151 aEntry >>= xPropSet;
2153 if ( !xPropSet.is() )
2155 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2156 return false;
2159 // Title
2160 rProps.aTitle = rURI.getName();
2162 // MediaType
2165 uno::Any aMediaType = xPropSet->getPropertyValue(u"MediaType"_ustr);
2166 if ( !( aMediaType >>= rProps.aMediaType ) )
2168 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2169 return false;
2172 catch ( beans::UnknownPropertyException const & )
2174 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2175 return false;
2177 catch ( lang::WrappedTargetException const & )
2179 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2180 return false;
2183 uno::Reference< container::XEnumerationAccess > xEnumAccess;
2184 aEntry >>= xEnumAccess;
2186 // ContentType / IsFolder / IsDocument
2187 if ( xEnumAccess.is() )
2189 // folder
2190 rProps.aContentType = getContentType( rURI.getScheme(), true );
2191 rProps.bIsDocument = false;
2192 rProps.bIsFolder = true;
2194 else
2196 // stream
2197 rProps.aContentType = getContentType( rURI.getScheme(), false );
2198 rProps.bIsDocument = true;
2199 rProps.bIsFolder = false;
2202 if ( rProps.bIsDocument )
2204 // Size ( only available for streams )
2207 uno::Any aSize = xPropSet->getPropertyValue(u"Size"_ustr);
2208 if ( !( aSize >>= rProps.nSize ) )
2210 OSL_FAIL( "Content::loadData - Got no Size value!" );
2211 return false;
2214 catch ( beans::UnknownPropertyException const & )
2216 OSL_FAIL( "Content::loadData - Got no Size value!" );
2217 return false;
2219 catch ( lang::WrappedTargetException const & )
2221 OSL_FAIL( "Content::loadData - Got no Size value!" );
2222 return false;
2225 // Compressed ( only available for streams )
2228 uno::Any aCompressed = xPropSet->getPropertyValue(u"Compressed"_ustr);
2229 if ( !( aCompressed >>= rProps.bCompressed ) )
2231 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2232 return false;
2235 catch ( beans::UnknownPropertyException const & )
2237 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2238 return false;
2240 catch ( lang::WrappedTargetException const & )
2242 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2243 return false;
2246 // Encrypted ( only available for streams )
2249 uno::Any aEncrypted = xPropSet->getPropertyValue(u"Encrypted"_ustr);
2250 if ( !( aEncrypted >>= rProps.bEncrypted ) )
2252 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2253 return false;
2256 catch ( beans::UnknownPropertyException const & )
2258 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2259 return false;
2261 catch ( lang::WrappedTargetException const & )
2263 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2264 return false;
2267 return true;
2270 catch ( container::NoSuchElementException const & )
2272 // getByHierarchicalName
2275 return false;
2279 void Content::renameData(
2280 const uno::Reference< ucb::XContentIdentifier >& xOldId,
2281 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2283 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2285 PackageUri aURI( xOldId->getContentIdentifier() );
2286 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2287 aURI );
2289 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2290 return;
2294 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2295 uno::Reference< container::XNamed > xNamed;
2296 aEntry >>= xNamed;
2298 if ( !xNamed.is() )
2300 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2301 return;
2304 PackageUri aNewURI( xNewId->getContentIdentifier() );
2306 // No success indicator!? No return value / exceptions specified.
2307 xNamed->setName( aNewURI.getName() );
2309 catch ( container::NoSuchElementException const & )
2311 // getByHierarchicalName
2316 bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2318 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2320 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2322 uno::Reference< beans::XPropertySet > xPackagePropSet(
2323 xNA, uno::UNO_QUERY );
2324 OSL_ENSURE( xPackagePropSet.is(),
2325 "Content::storeData - "
2326 "Got no XPropertySet interface from package!" );
2328 if ( !xPackagePropSet.is() )
2329 return false;
2331 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2333 if ( m_aUri.isRootFolder() )
2335 // Property available only from package and from streams (see below)
2338 xPackagePropSet->setPropertyValue(
2339 u"EncryptionKey"_ustr,
2340 uno::Any( m_aProps.aEncryptionKey ) );
2341 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2343 catch ( beans::UnknownPropertyException const & )
2345 // setPropertyValue
2347 catch ( beans::PropertyVetoException const & )
2349 // setPropertyValue
2351 catch ( lang::IllegalArgumentException const & )
2353 // setPropertyValue
2355 catch ( lang::WrappedTargetException const & )
2357 // setPropertyValue
2362 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2364 // if ( !bCreate )
2365 // return sal_True;
2369 // Create new resource...
2370 uno::Reference< lang::XSingleServiceFactory > xFac(
2371 xNA, uno::UNO_QUERY );
2372 if ( !xFac.is() )
2374 OSL_FAIL( "Content::storeData - "
2375 "Got no XSingleServiceFactory interface!" );
2376 return false;
2379 uno::Sequence< uno::Any > aArgs{ uno::Any(isFolder()) };
2381 uno::Reference< uno::XInterface > xNew
2382 = xFac->createInstanceWithArguments( aArgs );
2384 if ( !xNew.is() )
2386 OSL_FAIL( "Content::storeData - createInstance failed!" );
2387 return false;
2390 PackageUri aParentUri( getParentURL() );
2391 uno::Any aEntry
2392 = xNA->getByHierarchicalName( aParentUri.getPath() );
2393 uno::Reference< container::XNameContainer > xParentContainer;
2394 aEntry >>= xParentContainer;
2396 if ( !xParentContainer.is() )
2398 OSL_FAIL( "Content::storeData - "
2399 "Got no XNameContainer interface!" );
2400 return false;
2403 xParentContainer->insertByName( m_aProps.aTitle,
2404 uno::Any( xNew ) );
2406 catch ( lang::IllegalArgumentException const & )
2408 // insertByName
2409 OSL_FAIL( "Content::storeData - insertByName failed!" );
2410 return false;
2412 catch ( uno::RuntimeException const & )
2414 throw;
2416 catch ( container::ElementExistException const & )
2418 // insertByName
2419 OSL_FAIL( "Content::storeData - insertByName failed!" );
2420 return false;
2422 catch ( lang::WrappedTargetException const & )
2424 // insertByName
2425 OSL_FAIL( "Content::storeData - insertByName failed!" );
2426 return false;
2428 catch ( container::NoSuchElementException const & )
2430 // getByHierarchicalName
2431 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2432 return false;
2434 catch ( uno::Exception const & )
2436 // createInstanceWithArguments
2437 OSL_FAIL( "Content::storeData - Error!" );
2438 return false;
2442 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2443 return false;
2447 uno::Reference< beans::XPropertySet > xPropSet;
2448 xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2450 if ( !xPropSet.is() )
2452 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2453 return false;
2457 // Store property values...
2460 if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2462 xPropSet->setPropertyValue(
2463 u"MediaType"_ustr,
2464 uno::Any( m_aProps.aMediaType ) );
2465 m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2468 if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2470 if ( !isFolder() )
2471 xPropSet->setPropertyValue(
2472 u"Compressed"_ustr,
2473 uno::Any( m_aProps.bCompressed ) );
2475 m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2478 if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2480 if ( !isFolder() )
2481 xPropSet->setPropertyValue(
2482 u"Encrypted"_ustr,
2483 uno::Any( m_aProps.bEncrypted ) );
2485 m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2488 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2490 if ( !isFolder() )
2491 xPropSet->setPropertyValue(
2492 u"EncryptionKey"_ustr,
2493 uno::Any( m_aProps.aEncryptionKey ) );
2495 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2499 // Store data stream...
2502 if ( xStream.is() && !isFolder() )
2504 uno::Reference< io::XActiveDataSink > xSink(
2505 xPropSet, uno::UNO_QUERY );
2507 if ( !xSink.is() )
2509 OSL_FAIL( "Content::storeData - "
2510 "Got no XActiveDataSink interface!" );
2511 return false;
2514 xSink->setInputStream( xStream );
2517 return true;
2519 catch ( container::NoSuchElementException const & )
2521 // getByHierarchicalName
2523 catch ( beans::UnknownPropertyException const & )
2525 // setPropertyValue
2527 catch ( beans::PropertyVetoException const & )
2529 // setPropertyValue
2531 catch ( lang::IllegalArgumentException const & )
2533 // setPropertyValue
2535 catch ( lang::WrappedTargetException const & )
2537 // setPropertyValue
2540 OSL_FAIL( "Content::storeData - Error!" );
2541 return false;
2545 bool Content::removeData()
2547 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2549 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2551 PackageUri aParentUri( getParentURL() );
2552 if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2553 return false;
2557 uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2558 uno::Reference< container::XNameContainer > xContainer;
2559 aEntry >>= xContainer;
2561 if ( !xContainer.is() )
2563 OSL_FAIL( "Content::removeData - "
2564 "Got no XNameContainer interface!" );
2565 return false;
2568 xContainer->removeByName( m_aUri.getName() );
2569 return true;
2571 catch ( container::NoSuchElementException const & )
2573 // getByHierarchicalName, removeByName
2575 catch ( lang::WrappedTargetException const & )
2577 // removeByName
2580 OSL_FAIL( "Content::removeData - Error!" );
2581 return false;
2585 bool Content::flushData()
2587 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2589 // Note: XChangesBatch is only implemented by the package itself, not
2590 // by the single entries. Maybe this has to change...
2592 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2594 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2595 if ( !xBatch.is() )
2597 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2598 return false;
2603 xBatch->commitChanges();
2604 return true;
2606 catch ( lang::WrappedTargetException const & )
2610 OSL_FAIL( "Content::flushData - Error!" );
2611 return false;
2615 uno::Reference< io::XInputStream > Content::getInputStream()
2617 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2619 uno::Reference< io::XInputStream > xStream;
2620 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2622 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2623 return xStream;
2627 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2628 uno::Reference< io::XActiveDataSink > xSink;
2629 aEntry >>= xSink;
2631 if ( !xSink.is() )
2633 OSL_FAIL( "Content::getInputStream - "
2634 "Got no XActiveDataSink interface!" );
2635 return xStream;
2638 xStream = xSink->getInputStream();
2640 OSL_ENSURE( xStream.is(),
2641 "Content::getInputStream - Got no stream!" );
2643 catch ( container::NoSuchElementException const & )
2645 // getByHierarchicalName
2648 return xStream;
2652 uno::Reference< container::XEnumeration > Content::getIterator()
2654 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2656 uno::Reference< container::XEnumeration > xIter;
2657 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2659 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2660 return xIter;
2664 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2665 uno::Reference< container::XEnumerationAccess > xIterFac;
2666 aEntry >>= xIterFac;
2668 if ( !xIterFac.is() )
2670 OSL_FAIL( "Content::getIterator - "
2671 "Got no XEnumerationAccess interface!" );
2672 return xIter;
2675 xIter = xIterFac->createEnumeration();
2677 OSL_ENSURE( xIter.is(),
2678 "Content::getIterator - Got no iterator!" );
2680 catch ( container::NoSuchElementException const & )
2682 // getByHierarchicalName
2685 return xIter;
2688 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */