fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / ucb / source / ucp / package / pkgcontent.cxx
blobd19cccb956e10aa1fffc3c6e0ee298c4e2e01011
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
24 *************************************************************************/
25 #include <osl/diagnose.h>
27 #include "osl/doublecheckedlocking.h"
28 #include <rtl/ustring.h>
29 #include <rtl/ustring.hxx>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/beans/PropertyState.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/XPropertyAccess.hpp>
34 #include <com/sun/star/container/XEnumerationAccess.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/lang/IllegalAccessException.hpp>
42 #include <com/sun/star/sdbc/XRow.hpp>
43 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
44 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
45 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
46 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
47 #include <com/sun/star/ucb/NameClash.hpp>
48 #include <com/sun/star/ucb/NameClashException.hpp>
49 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
50 #include <com/sun/star/ucb/OpenMode.hpp>
51 #include <com/sun/star/ucb/TransferInfo.hpp>
52 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
53 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
54 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
55 #include <com/sun/star/ucb/XCommandInfo.hpp>
56 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
57 #include <com/sun/star/util/XChangesBatch.hpp>
58 #include <com/sun/star/uno/Any.hxx>
59 #include <com/sun/star/uno/Sequence.hxx>
60 #include <comphelper/processfactory.hxx>
61 #include <ucbhelper/contentidentifier.hxx>
62 #include <ucbhelper/propertyvalueset.hxx>
63 #include <ucbhelper/cancelcommandexecution.hxx>
64 #include "pkgcontent.hxx"
65 #include "pkgprovider.hxx"
66 #include "pkgresultset.hxx"
68 #include "../inc/urihelper.hxx"
70 using namespace com::sun::star;
71 using namespace package_ucp;
73 #define NONE_MODIFIED sal_uInt32( 0x00 )
74 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
75 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
76 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
77 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
79 //=========================================================================
80 //=========================================================================
82 // ContentProperties Implementation.
84 //=========================================================================
85 //=========================================================================
87 ContentProperties::ContentProperties( const OUString& rContentType )
88 : aContentType( rContentType ),
89 nSize( 0 ),
90 bCompressed( sal_True ),
91 bEncrypted( sal_False ),
92 bHasEncryptedEntries( sal_False )
94 bIsFolder = rContentType == PACKAGE_FOLDER_CONTENT_TYPE || rContentType == PACKAGE_ZIP_FOLDER_CONTENT_TYPE;
95 bIsDocument = !bIsFolder;
97 OSL_ENSURE( bIsFolder || rContentType == PACKAGE_STREAM_CONTENT_TYPE || rContentType == PACKAGE_ZIP_STREAM_CONTENT_TYPE,
98 "ContentProperties::ContentProperties - Unknown type!" );
101 //=========================================================================
103 uno::Sequence< ucb::ContentInfo >
104 ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const
106 if ( bIsFolder )
108 uno::Sequence< beans::Property > aProps( 1 );
109 aProps.getArray()[ 0 ] = beans::Property(
110 OUString("Title"),
112 getCppuType( static_cast< const OUString * >( 0 ) ),
113 beans::PropertyAttribute::BOUND );
115 uno::Sequence< ucb::ContentInfo > aSeq( 2 );
117 // Folder.
118 aSeq.getArray()[ 0 ].Type
119 = Content::getContentType( rUri.getScheme(), sal_True );
120 aSeq.getArray()[ 0 ].Attributes
121 = ucb::ContentInfoAttribute::KIND_FOLDER;
122 aSeq.getArray()[ 0 ].Properties = aProps;
124 // Stream.
125 aSeq.getArray()[ 1 ].Type
126 = Content::getContentType( rUri.getScheme(), sal_False );
127 aSeq.getArray()[ 1 ].Attributes
128 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
129 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
130 aSeq.getArray()[ 1 ].Properties = aProps;
132 return aSeq;
134 else
136 return uno::Sequence< ucb::ContentInfo >( 0 );
140 //=========================================================================
141 //=========================================================================
143 // Content Implementation.
145 //=========================================================================
146 //=========================================================================
148 // static ( "virtual" ctor )
149 Content* Content::create(
150 const uno::Reference< uno::XComponentContext >& rxContext,
151 ContentProvider* pProvider,
152 const uno::Reference< ucb::XContentIdentifier >& Identifier )
154 OUString aURL = Identifier->getContentIdentifier();
155 PackageUri aURI( aURL );
156 ContentProperties aProps;
157 uno::Reference< container::XHierarchicalNameAccess > xPackage;
159 if ( loadData( pProvider, aURI, aProps, xPackage ) )
161 // resource exists
163 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
164 if ( ( nLastSlash + 1 ) == aURL.getLength() )
166 // Client explicitly requested a folder!
167 if ( !aProps.bIsFolder )
168 return 0;
171 uno::Reference< ucb::XContentIdentifier > xId
172 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
173 return new Content( rxContext, pProvider, xId, xPackage, aURI, aProps );
175 else
177 // resource doesn't exist
179 sal_Bool bFolder = sal_False;
181 // Guess type according to URI.
182 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' );
183 if ( ( nLastSlash + 1 ) == aURL.getLength() )
184 bFolder = sal_True;
186 uno::Reference< ucb::XContentIdentifier > xId
187 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
189 ucb::ContentInfo aInfo;
190 if ( bFolder || aURI.isRootFolder() )
191 aInfo.Type = getContentType( aURI.getScheme(), sal_True );
192 else
193 aInfo.Type = getContentType( aURI.getScheme(), sal_False );
195 return new Content( rxContext, pProvider, xId, xPackage, aURI, aInfo );
199 //=========================================================================
200 // static ( "virtual" ctor )
201 Content* Content::create(
202 const uno::Reference< uno::XComponentContext >& rxContext,
203 ContentProvider* pProvider,
204 const uno::Reference< ucb::XContentIdentifier >& Identifier,
205 const ucb::ContentInfo& Info )
207 if ( Info.Type.isEmpty() )
208 return 0;
210 PackageUri aURI( Identifier->getContentIdentifier() );
212 if ( !Info.Type.equalsIgnoreAsciiCase(
213 getContentType( aURI.getScheme(), sal_True ) ) &&
214 !Info.Type.equalsIgnoreAsciiCase(
215 getContentType( aURI.getScheme(), sal_False ) ) )
216 return 0;
218 uno::Reference< container::XHierarchicalNameAccess > xPackage;
220 xPackage = pProvider->createPackage( aURI.getPackage(), aURI.getParam() );
222 uno::Reference< ucb::XContentIdentifier > xId
223 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
224 return new Content( rxContext, pProvider, xId, xPackage, aURI, Info );
227 //=========================================================================
228 // static
229 OUString Content::getContentType(
230 const OUString& aScheme, sal_Bool bFolder )
232 return ( OUString("application/")
233 + aScheme
234 + ( bFolder
235 ? OUString("-folder")
236 : OUString("-stream") ) );
239 //=========================================================================
240 Content::Content(
241 const uno::Reference< uno::XComponentContext >& rxContext,
242 ContentProvider* pProvider,
243 const uno::Reference< ucb::XContentIdentifier >& Identifier,
244 const uno::Reference< container::XHierarchicalNameAccess > & Package,
245 const PackageUri& rUri,
246 const ContentProperties& rProps )
247 : ContentImplHelper( rxContext, pProvider, Identifier ),
248 m_aUri( rUri ),
249 m_aProps( rProps ),
250 m_eState( PERSISTENT ),
251 m_xPackage( Package ),
252 m_pProvider( pProvider ),
253 m_nModifiedProps( NONE_MODIFIED )
257 //=========================================================================
258 Content::Content(
259 const uno::Reference< uno::XComponentContext >& rxContext,
260 ContentProvider* pProvider,
261 const uno::Reference< ucb::XContentIdentifier >& Identifier,
262 const uno::Reference< container::XHierarchicalNameAccess > & Package,
263 const PackageUri& rUri,
264 const ucb::ContentInfo& Info )
265 : ContentImplHelper( rxContext, pProvider, Identifier ),
266 m_aUri( rUri ),
267 m_aProps( Info.Type ),
268 m_eState( TRANSIENT ),
269 m_xPackage( Package ),
270 m_pProvider( pProvider ),
271 m_nModifiedProps( NONE_MODIFIED )
275 //=========================================================================
276 // virtual
277 Content::~Content()
281 //=========================================================================
283 // XInterface methods.
285 //=========================================================================
287 // virtual
288 void SAL_CALL Content::acquire()
289 throw( )
291 ContentImplHelper::acquire();
294 //=========================================================================
295 // virtual
296 void SAL_CALL Content::release()
297 throw( )
299 ContentImplHelper::release();
302 //=========================================================================
303 // virtual
304 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
305 throw ( uno::RuntimeException )
307 uno::Any aRet;
309 if ( isFolder() )
310 aRet = cppu::queryInterface(
311 rType, static_cast< ucb::XContentCreator * >( this ) );
313 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
316 //=========================================================================
318 // XTypeProvider methods.
320 //=========================================================================
322 XTYPEPROVIDER_COMMON_IMPL( Content );
324 //=========================================================================
325 // virtual
326 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
327 throw( uno::RuntimeException )
329 cppu::OTypeCollection * pCollection = 0;
331 if ( isFolder() )
333 static cppu::OTypeCollection* pFolderTypes = 0;
335 pCollection = pFolderTypes;
336 if ( !pCollection )
338 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
340 pCollection = pFolderTypes;
341 if ( !pCollection )
343 static cppu::OTypeCollection aCollection(
344 CPPU_TYPE_REF( lang::XTypeProvider ),
345 CPPU_TYPE_REF( lang::XServiceInfo ),
346 CPPU_TYPE_REF( lang::XComponent ),
347 CPPU_TYPE_REF( ucb::XContent ),
348 CPPU_TYPE_REF( ucb::XCommandProcessor ),
349 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
350 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
351 CPPU_TYPE_REF( beans::XPropertyContainer ),
352 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
353 CPPU_TYPE_REF( container::XChild ),
354 CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
355 pCollection = &aCollection;
356 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
357 pFolderTypes = pCollection;
360 else {
361 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
364 else
366 static cppu::OTypeCollection* pDocumentTypes = 0;
368 pCollection = pDocumentTypes;
369 if ( !pCollection )
371 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
373 pCollection = pDocumentTypes;
374 if ( !pCollection )
376 static cppu::OTypeCollection aCollection(
377 CPPU_TYPE_REF( lang::XTypeProvider ),
378 CPPU_TYPE_REF( lang::XServiceInfo ),
379 CPPU_TYPE_REF( lang::XComponent ),
380 CPPU_TYPE_REF( ucb::XContent ),
381 CPPU_TYPE_REF( ucb::XCommandProcessor ),
382 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
383 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
384 CPPU_TYPE_REF( beans::XPropertyContainer ),
385 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
386 CPPU_TYPE_REF( container::XChild ) );
387 pCollection = &aCollection;
388 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
389 pDocumentTypes = pCollection;
392 else {
393 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
397 return (*pCollection).getTypes();
400 //=========================================================================
402 // XServiceInfo methods.
404 //=========================================================================
406 // virtual
407 OUString SAL_CALL Content::getImplementationName()
408 throw( uno::RuntimeException )
410 return OUString( "com.sun.star.comp.ucb.PackageContent" );
413 //=========================================================================
414 // virtual
415 uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
416 throw( uno::RuntimeException )
418 uno::Sequence< OUString > aSNS( 1 );
419 if ( isFolder() )
420 aSNS.getArray()[ 0 ] = OUString( PACKAGE_FOLDER_CONTENT_SERVICE_NAME );
421 else
422 aSNS.getArray()[ 0 ] = OUString( PACKAGE_STREAM_CONTENT_SERVICE_NAME );
424 return aSNS;
427 //=========================================================================
429 // XContent methods.
431 //=========================================================================
433 // virtual
434 OUString SAL_CALL Content::getContentType()
435 throw( uno::RuntimeException )
437 return m_aProps.aContentType;
440 //=========================================================================
442 // XCommandProcessor methods.
444 //=========================================================================
446 // virtual
447 uno::Any SAL_CALL Content::execute(
448 const ucb::Command& aCommand,
449 sal_Int32 /*CommandId*/,
450 const uno::Reference< ucb::XCommandEnvironment >& Environment )
451 throw( uno::Exception,
452 ucb::CommandAbortedException,
453 uno::RuntimeException )
455 uno::Any aRet;
457 if ( aCommand.Name == "getPropertyValues" )
459 //////////////////////////////////////////////////////////////////
460 // getPropertyValues
461 //////////////////////////////////////////////////////////////////
463 uno::Sequence< beans::Property > Properties;
464 if ( !( aCommand.Argument >>= Properties ) )
466 ucbhelper::cancelCommandExecution(
467 uno::makeAny( lang::IllegalArgumentException(
468 OUString( "Wrong argument type!" ),
469 static_cast< cppu::OWeakObject * >( this ),
470 -1 ) ),
471 Environment );
472 // Unreachable
475 aRet <<= getPropertyValues( Properties );
477 else if ( aCommand.Name == "setPropertyValues" )
479 //////////////////////////////////////////////////////////////////
480 // setPropertyValues
481 //////////////////////////////////////////////////////////////////
483 uno::Sequence< beans::PropertyValue > aProperties;
484 if ( !( aCommand.Argument >>= aProperties ) )
486 ucbhelper::cancelCommandExecution(
487 uno::makeAny( lang::IllegalArgumentException(
488 OUString( "Wrong argument type!" ),
489 static_cast< cppu::OWeakObject * >( this ),
490 -1 ) ),
491 Environment );
492 // Unreachable
495 if ( !aProperties.getLength() )
497 ucbhelper::cancelCommandExecution(
498 uno::makeAny( lang::IllegalArgumentException(
499 OUString( "No properties!" ),
500 static_cast< cppu::OWeakObject * >( this ),
501 -1 ) ),
502 Environment );
503 // Unreachable
506 aRet <<= setPropertyValues( aProperties, Environment );
508 else if ( aCommand.Name == "getPropertySetInfo" )
510 //////////////////////////////////////////////////////////////////
511 // getPropertySetInfo
512 //////////////////////////////////////////////////////////////////
514 // Note: Implemented by base class.
515 aRet <<= getPropertySetInfo( Environment );
517 else if ( aCommand.Name == "getCommandInfo" )
519 //////////////////////////////////////////////////////////////////
520 // getCommandInfo
521 //////////////////////////////////////////////////////////////////
523 // Note: Implemented by base class.
524 aRet <<= getCommandInfo( Environment );
526 else if ( aCommand.Name == "open" )
528 //////////////////////////////////////////////////////////////////
529 // open
530 //////////////////////////////////////////////////////////////////
532 ucb::OpenCommandArgument2 aOpenCommand;
533 if ( !( aCommand.Argument >>= aOpenCommand ) )
535 ucbhelper::cancelCommandExecution(
536 uno::makeAny( lang::IllegalArgumentException(
537 OUString( "Wrong argument type!" ),
538 static_cast< cppu::OWeakObject * >( this ),
539 -1 ) ),
540 Environment );
541 // Unreachable
544 aRet = open( aOpenCommand, Environment );
546 else if ( !m_aUri.isRootFolder() && aCommand.Name == "insert" )
548 //////////////////////////////////////////////////////////////////
549 // insert
550 //////////////////////////////////////////////////////////////////
552 ucb::InsertCommandArgument aArg;
553 if ( !( aCommand.Argument >>= aArg ) )
555 ucbhelper::cancelCommandExecution(
556 uno::makeAny( lang::IllegalArgumentException(
557 OUString( "Wrong argument type!" ),
558 static_cast< cppu::OWeakObject * >( this ),
559 -1 ) ),
560 Environment );
561 // Unreachable
564 sal_Int32 nNameClash = aArg.ReplaceExisting
565 ? ucb::NameClash::OVERWRITE
566 : ucb::NameClash::ERROR;
567 insert( aArg.Data, nNameClash, Environment );
569 else if ( !m_aUri.isRootFolder() && aCommand.Name == "delete" )
571 //////////////////////////////////////////////////////////////////
572 // delete
573 //////////////////////////////////////////////////////////////////
575 sal_Bool bDeletePhysical = sal_False;
576 aCommand.Argument >>= bDeletePhysical;
577 destroy( bDeletePhysical, Environment );
579 // Remove own and all children's persistent data.
580 if ( !removeData() )
582 uno::Any aProps
583 = uno::makeAny(
584 beans::PropertyValue(
585 OUString( "Uri"),
587 uno::makeAny(m_xIdentifier->
588 getContentIdentifier()),
589 beans::PropertyState_DIRECT_VALUE));
590 ucbhelper::cancelCommandExecution(
591 ucb::IOErrorCode_CANT_WRITE,
592 uno::Sequence< uno::Any >(&aProps, 1),
593 Environment,
594 OUString( "Cannot remove persistent data!" ),
595 this );
596 // Unreachable
599 // Remove own and all children's Additional Core Properties.
600 removeAdditionalPropertySet( sal_True );
602 else if ( aCommand.Name == "transfer" )
604 //////////////////////////////////////////////////////////////////
605 // transfer
606 // ( Not available at stream objects )
607 //////////////////////////////////////////////////////////////////
609 ucb::TransferInfo aInfo;
610 if ( !( aCommand.Argument >>= aInfo ) )
612 ucbhelper::cancelCommandExecution(
613 uno::makeAny( lang::IllegalArgumentException(
614 OUString( "Wrong argument type!" ),
615 static_cast< cppu::OWeakObject * >( this ),
616 -1 ) ),
617 Environment );
618 // Unreachable
621 transfer( aInfo, Environment );
623 else if ( aCommand.Name == "createNewContent" && isFolder() )
625 //////////////////////////////////////////////////////////////////
626 // createNewContent
627 // ( Not available at stream objects )
628 //////////////////////////////////////////////////////////////////
630 ucb::ContentInfo aInfo;
631 if ( !( aCommand.Argument >>= aInfo ) )
633 OSL_FAIL( "Wrong argument type!" );
634 ucbhelper::cancelCommandExecution(
635 uno::makeAny( lang::IllegalArgumentException(
636 OUString( "Wrong argument type!" ),
637 static_cast< cppu::OWeakObject * >( this ),
638 -1 ) ),
639 Environment );
640 // Unreachable
643 aRet <<= createNewContent( aInfo );
645 else if ( aCommand.Name == "flush" )
647 //////////////////////////////////////////////////////////////////
648 // flush
649 // ( Not available at stream objects )
650 //////////////////////////////////////////////////////////////////
652 if( !flushData() )
654 uno::Any aProps
655 = uno::makeAny(
656 beans::PropertyValue(
657 OUString( "Uri"),
659 uno::makeAny(m_xIdentifier->
660 getContentIdentifier()),
661 beans::PropertyState_DIRECT_VALUE));
662 ucbhelper::cancelCommandExecution(
663 ucb::IOErrorCode_CANT_WRITE,
664 uno::Sequence< uno::Any >(&aProps, 1),
665 Environment,
666 OUString( "Cannot write file to disk!" ),
667 this );
668 // Unreachable
671 else
673 //////////////////////////////////////////////////////////////////
674 // Unsupported command
675 //////////////////////////////////////////////////////////////////
677 ucbhelper::cancelCommandExecution(
678 uno::makeAny( ucb::UnsupportedCommandException(
679 OUString(),
680 static_cast< cppu::OWeakObject * >( this ) ) ),
681 Environment );
682 // Unreachable
685 return aRet;
688 //=========================================================================
689 // virtual
690 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
691 throw( uno::RuntimeException )
693 // @@@ Implement logic to abort running commands, if this makes
694 // sense for your content.
697 //=========================================================================
699 // XContentCreator methods.
701 //=========================================================================
703 // virtual
704 uno::Sequence< ucb::ContentInfo > SAL_CALL
705 Content::queryCreatableContentsInfo()
706 throw( uno::RuntimeException )
708 return m_aProps.getCreatableContentsInfo( m_aUri );
711 //=========================================================================
712 // virtual
713 uno::Reference< ucb::XContent > SAL_CALL
714 Content::createNewContent( const ucb::ContentInfo& Info )
715 throw( uno::RuntimeException )
717 if ( isFolder() )
719 osl::Guard< osl::Mutex > aGuard( m_aMutex );
721 if ( Info.Type.isEmpty() )
722 return uno::Reference< ucb::XContent >();
724 if ( !Info.Type.equalsIgnoreAsciiCase(
725 getContentType( m_aUri.getScheme(), sal_True ) ) &&
726 !Info.Type.equalsIgnoreAsciiCase(
727 getContentType( m_aUri.getScheme(), sal_False ) ) )
728 return uno::Reference< ucb::XContent >();
730 OUString aURL = m_aUri.getUri();
731 aURL += OUString("/");
733 if ( Info.Type.equalsIgnoreAsciiCase(
734 getContentType( m_aUri.getScheme(), sal_True ) ) )
735 aURL += OUString("New_Folder");
736 else
737 aURL += OUString("New_Stream");
739 uno::Reference< ucb::XContentIdentifier > xId(
740 new ::ucbhelper::ContentIdentifier( aURL ) );
742 return create( m_xContext, m_pProvider, xId, Info );
744 else
746 OSL_FAIL( "createNewContent called on non-folder object!" );
747 return uno::Reference< ucb::XContent >();
751 //=========================================================================
753 // Non-interface methods.
755 //=========================================================================
757 // virtual
758 OUString Content::getParentURL()
760 return m_aUri.getParentUri();
763 //=========================================================================
764 // static
765 uno::Reference< sdbc::XRow > Content::getPropertyValues(
766 const uno::Reference< uno::XComponentContext >& rxContext,
767 const uno::Sequence< beans::Property >& rProperties,
768 ContentProvider* pProvider,
769 const OUString& rContentId )
771 ContentProperties aData;
772 uno::Reference< container::XHierarchicalNameAccess > xPackage;
773 if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) )
775 return getPropertyValues( rxContext,
776 rProperties,
777 aData,
778 rtl::Reference<
779 ::ucbhelper::ContentProviderImplHelper >(
780 pProvider ),
781 rContentId );
783 else
785 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
786 = new ::ucbhelper::PropertyValueSet( rxContext );
788 sal_Int32 nCount = rProperties.getLength();
789 if ( nCount )
791 const beans::Property* pProps = rProperties.getConstArray();
792 for ( sal_Int32 n = 0; n < nCount; ++n )
793 xRow->appendVoid( pProps[ n ] );
796 return uno::Reference< sdbc::XRow >( xRow.get() );
800 //=========================================================================
801 // static
802 uno::Reference< sdbc::XRow > Content::getPropertyValues(
803 const uno::Reference< uno::XComponentContext >& rxContext,
804 const uno::Sequence< beans::Property >& rProperties,
805 const ContentProperties& rData,
806 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >&
807 rProvider,
808 const OUString& rContentId )
810 // Note: Empty sequence means "get values of all supported properties".
812 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
813 = new ::ucbhelper::PropertyValueSet( rxContext );
815 sal_Int32 nCount = rProperties.getLength();
816 if ( nCount )
818 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
819 sal_Bool bTriedToGetAdditonalPropSet = sal_False;
821 const beans::Property* pProps = rProperties.getConstArray();
822 for ( sal_Int32 n = 0; n < nCount; ++n )
824 const beans::Property& rProp = pProps[ n ];
826 // Process Core properties.
828 if ( rProp.Name == "ContentType" )
830 xRow->appendString ( rProp, rData.aContentType );
832 else if ( rProp.Name == "Title" )
834 xRow->appendString ( rProp, rData.aTitle );
836 else if ( rProp.Name == "IsDocument" )
838 xRow->appendBoolean( rProp, rData.bIsDocument );
840 else if ( rProp.Name == "IsFolder" )
842 xRow->appendBoolean( rProp, rData.bIsFolder );
844 else if ( rProp.Name == "CreatableContentsInfo" )
846 xRow->appendObject(
847 rProp, uno::makeAny(
848 rData.getCreatableContentsInfo(
849 PackageUri( rContentId ) ) ) );
851 else if ( rProp.Name == "MediaType" )
853 xRow->appendString ( rProp, rData.aMediaType );
855 else if ( rProp.Name == "Size" )
857 // Property only available for streams.
858 if ( rData.bIsDocument )
859 xRow->appendLong( rProp, rData.nSize );
860 else
861 xRow->appendVoid( rProp );
863 else if ( rProp.Name == "Compressed" )
865 // Property only available for streams.
866 if ( rData.bIsDocument )
867 xRow->appendBoolean( rProp, rData.bCompressed );
868 else
869 xRow->appendVoid( rProp );
871 else if ( rProp.Name == "Encrypted" )
873 // Property only available for streams.
874 if ( rData.bIsDocument )
875 xRow->appendBoolean( rProp, rData.bEncrypted );
876 else
877 xRow->appendVoid( rProp );
879 else if ( rProp.Name == "HasEncryptedEntries" )
881 // Property only available for root folder.
882 PackageUri aURI( rContentId );
883 if ( aURI.isRootFolder() )
884 xRow->appendBoolean( rProp, rData.bHasEncryptedEntries );
885 else
886 xRow->appendVoid( rProp );
888 else
890 // Not a Core Property! Maybe it's an Additional Core Property?!
892 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
894 xAdditionalPropSet
895 = uno::Reference< beans::XPropertySet >(
896 rProvider->getAdditionalPropertySet( rContentId,
897 sal_False ),
898 uno::UNO_QUERY );
899 bTriedToGetAdditonalPropSet = sal_True;
902 if ( xAdditionalPropSet.is() )
904 if ( !xRow->appendPropertySetValue(
905 xAdditionalPropSet,
906 rProp ) )
908 // Append empty entry.
909 xRow->appendVoid( rProp );
912 else
914 // Append empty entry.
915 xRow->appendVoid( rProp );
920 else
922 // Append all Core Properties.
923 xRow->appendString (
924 beans::Property(
925 OUString("ContentType"),
927 getCppuType( static_cast< const OUString * >( 0 ) ),
928 beans::PropertyAttribute::BOUND
929 | beans::PropertyAttribute::READONLY ),
930 rData.aContentType );
931 xRow->appendString(
932 beans::Property(
933 OUString("Title"),
935 getCppuType( static_cast< const OUString * >( 0 ) ),
936 beans::PropertyAttribute::BOUND ),
937 rData.aTitle );
938 xRow->appendBoolean(
939 beans::Property(
940 OUString("IsDocument"),
942 getCppuBooleanType(),
943 beans::PropertyAttribute::BOUND
944 | beans::PropertyAttribute::READONLY ),
945 rData.bIsDocument );
946 xRow->appendBoolean(
947 beans::Property(
948 OUString("IsFolder"),
950 getCppuBooleanType(),
951 beans::PropertyAttribute::BOUND
952 | beans::PropertyAttribute::READONLY ),
953 rData.bIsFolder );
954 xRow->appendObject(
955 beans::Property(
956 OUString("CreatableContentsInfo"),
958 getCppuType( static_cast<
959 const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
960 beans::PropertyAttribute::BOUND
961 | beans::PropertyAttribute::READONLY ),
962 uno::makeAny(
963 rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) );
964 xRow->appendString(
965 beans::Property(
966 OUString("MediaType"),
968 getCppuType( static_cast< const OUString * >( 0 ) ),
969 beans::PropertyAttribute::BOUND ),
970 rData.aMediaType );
972 // Properties only available for streams.
973 if ( rData.bIsDocument )
975 xRow->appendLong(
976 beans::Property(
977 OUString("Size"),
979 getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
980 beans::PropertyAttribute::BOUND
981 | beans::PropertyAttribute::READONLY ),
982 rData.nSize );
984 xRow->appendBoolean(
985 beans::Property(
986 OUString("Compressed"),
988 getCppuBooleanType(),
989 beans::PropertyAttribute::BOUND ),
990 rData.bCompressed );
992 xRow->appendBoolean(
993 beans::Property(
994 OUString("Encrypted"),
996 getCppuBooleanType(),
997 beans::PropertyAttribute::BOUND ),
998 rData.bEncrypted );
1001 // Properties only available for root folder.
1002 PackageUri aURI( rContentId );
1003 if ( aURI.isRootFolder() )
1005 xRow->appendBoolean(
1006 beans::Property(
1007 OUString("HasEncryptedEntries"),
1009 getCppuBooleanType(),
1010 beans::PropertyAttribute::BOUND
1011 | beans::PropertyAttribute::READONLY ),
1012 rData.bHasEncryptedEntries );
1015 // Append all Additional Core Properties.
1017 uno::Reference< beans::XPropertySet > xSet(
1018 rProvider->getAdditionalPropertySet( rContentId, sal_False ),
1019 uno::UNO_QUERY );
1020 xRow->appendPropertySet( xSet );
1023 return uno::Reference< sdbc::XRow >( xRow.get() );
1026 //=========================================================================
1027 uno::Reference< sdbc::XRow > Content::getPropertyValues(
1028 const uno::Sequence< beans::Property >& rProperties )
1030 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1031 return getPropertyValues( m_xContext,
1032 rProperties,
1033 m_aProps,
1034 rtl::Reference<
1035 ::ucbhelper::ContentProviderImplHelper >(
1036 m_xProvider.get() ),
1037 m_xIdentifier->getContentIdentifier() );
1040 //=========================================================================
1041 uno::Sequence< uno::Any > Content::setPropertyValues(
1042 const uno::Sequence< beans::PropertyValue >& rValues,
1043 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1044 throw( uno::Exception )
1046 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1048 uno::Sequence< uno::Any > aRet( rValues.getLength() );
1049 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
1050 sal_Int32 nChanged = 0;
1052 beans::PropertyChangeEvent aEvent;
1053 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
1054 aEvent.Further = sal_False;
1055 // aEvent.PropertyName =
1056 aEvent.PropertyHandle = -1;
1057 // aEvent.OldValue =
1058 // aEvent.NewValue =
1060 const beans::PropertyValue* pValues = rValues.getConstArray();
1061 sal_Int32 nCount = rValues.getLength();
1063 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
1064 sal_Bool bTriedToGetAdditonalPropSet = sal_False;
1065 sal_Bool bExchange = sal_False;
1066 sal_Bool bStore = sal_False;
1067 OUString aNewTitle;
1068 sal_Int32 nTitlePos = -1;
1070 for ( sal_Int32 n = 0; n < nCount; ++n )
1072 const beans::PropertyValue& rValue = pValues[ n ];
1074 if ( rValue.Name == "ContentType" )
1076 // Read-only property!
1077 aRet[ n ] <<= lang::IllegalAccessException(
1078 OUString(
1079 "Property is read-only!" ),
1080 static_cast< cppu::OWeakObject * >( this ) );
1082 else if ( rValue.Name == "IsDocument" )
1084 // Read-only property!
1085 aRet[ n ] <<= lang::IllegalAccessException(
1086 OUString(
1087 "Property is read-only!" ),
1088 static_cast< cppu::OWeakObject * >( this ) );
1090 else if ( rValue.Name == "IsFolder" )
1092 // Read-only property!
1093 aRet[ n ] <<= lang::IllegalAccessException(
1094 OUString(
1095 "Property is read-only!" ),
1096 static_cast< cppu::OWeakObject * >( this ) );
1098 else if ( rValue.Name == "CreatableContentsInfo" )
1100 // Read-only property!
1101 aRet[ n ] <<= lang::IllegalAccessException(
1102 OUString(
1103 "Property is read-only!" ),
1104 static_cast< cppu::OWeakObject * >( this ) );
1106 else if ( rValue.Name == "Title" )
1108 if ( m_aUri.isRootFolder() )
1110 // Read-only property!
1111 aRet[ n ] <<= lang::IllegalAccessException(
1112 OUString(
1113 "Property is read-only!" ),
1114 static_cast< cppu::OWeakObject * >( this ) );
1116 else
1118 OUString aNewValue;
1119 if ( rValue.Value >>= aNewValue )
1121 // No empty titles!
1122 if ( !aNewValue.isEmpty() )
1124 if ( aNewValue != m_aProps.aTitle )
1126 // modified title -> modified URL -> exchange !
1127 if ( m_eState == PERSISTENT )
1128 bExchange = sal_True;
1130 // new value will be set later...
1131 aNewTitle = aNewValue;
1133 // remember position within sequence of values
1134 // (for error handling).
1135 nTitlePos = n;
1138 else
1140 aRet[ n ] <<=
1141 lang::IllegalArgumentException(
1142 OUString(
1143 "Empty title not allowed!" ),
1144 static_cast< cppu::OWeakObject * >( this ),
1145 -1 );
1148 else
1150 aRet[ n ] <<=
1151 beans::IllegalTypeException(
1152 OUString(
1153 "Property value has wrong type!" ),
1154 static_cast< cppu::OWeakObject * >( this ) );
1158 else if ( rValue.Name == "MediaType" )
1160 OUString aNewValue;
1161 if ( rValue.Value >>= aNewValue )
1163 if ( aNewValue != m_aProps.aMediaType )
1165 aEvent.PropertyName = rValue.Name;
1166 aEvent.OldValue = uno::makeAny( m_aProps.aMediaType );
1167 aEvent.NewValue = uno::makeAny( aNewValue );
1169 m_aProps.aMediaType = aNewValue;
1170 nChanged++;
1171 bStore = sal_True;
1172 m_nModifiedProps |= MEDIATYPE_MODIFIED;
1175 else
1177 aRet[ n ] <<= beans::IllegalTypeException(
1178 OUString(
1179 "Property value has wrong type!" ),
1180 static_cast< cppu::OWeakObject * >( this ) );
1183 else if ( rValue.Name == "Size" )
1185 // Read-only property!
1186 aRet[ n ] <<= lang::IllegalAccessException(
1187 OUString(
1188 "Property is read-only!" ),
1189 static_cast< cppu::OWeakObject * >( this ) );
1191 else if ( rValue.Name == "Compressed" )
1193 // Property only available for streams.
1194 if ( m_aProps.bIsDocument )
1196 sal_Bool bNewValue;
1197 if ( rValue.Value >>= bNewValue )
1199 if ( bNewValue != m_aProps.bCompressed )
1201 aEvent.PropertyName = rValue.Name;
1202 aEvent.OldValue = uno::makeAny( m_aProps.bCompressed );
1203 aEvent.NewValue = uno::makeAny( bNewValue );
1205 m_aProps.bCompressed = bNewValue;
1206 nChanged++;
1207 bStore = sal_True;
1208 m_nModifiedProps |= COMPRESSED_MODIFIED;
1211 else
1213 aRet[ n ] <<= beans::IllegalTypeException(
1214 OUString(
1215 "Property value has wrong type!" ),
1216 static_cast< cppu::OWeakObject * >( this ) );
1219 else
1221 aRet[ n ] <<= beans::UnknownPropertyException(
1222 OUString(
1223 "Compressed only supported by streams!" ),
1224 static_cast< cppu::OWeakObject * >( this ) );
1227 else if ( rValue.Name == "Encrypted" )
1229 // Property only available for streams.
1230 if ( m_aProps.bIsDocument )
1232 sal_Bool bNewValue;
1233 if ( rValue.Value >>= bNewValue )
1235 if ( bNewValue != m_aProps.bEncrypted )
1237 aEvent.PropertyName = rValue.Name;
1238 aEvent.OldValue = uno::makeAny( m_aProps.bEncrypted );
1239 aEvent.NewValue = uno::makeAny( bNewValue );
1241 m_aProps.bEncrypted = bNewValue;
1242 nChanged++;
1243 bStore = sal_True;
1244 m_nModifiedProps |= ENCRYPTED_MODIFIED;
1247 else
1249 aRet[ n ] <<= beans::IllegalTypeException(
1250 OUString(
1251 "Property value has wrong type!" ),
1252 static_cast< cppu::OWeakObject * >( this ) );
1255 else
1257 aRet[ n ] <<= beans::UnknownPropertyException(
1258 OUString(
1259 "Encrypted only supported by streams!" ),
1260 static_cast< cppu::OWeakObject * >( this ) );
1263 else if ( rValue.Name == "HasEncryptedEntries" )
1265 // Read-only property!
1266 aRet[ n ] <<= lang::IllegalAccessException(
1267 OUString(
1268 "Property is read-only!" ),
1269 static_cast< cppu::OWeakObject * >( this ) );
1271 else if ( rValue.Name == "EncryptionKey" )
1273 // @@@ This is a temporary solution. In the future submitting
1274 // the key should be done using an interaction handler!
1276 // Write-Only property. Only supported by root folder and streams
1277 // (all non-root folders of a package have the same encryption key).
1278 if ( m_aUri.isRootFolder() || m_aProps.bIsDocument )
1280 uno::Sequence < sal_Int8 > aNewValue;
1281 if ( rValue.Value >>= aNewValue )
1283 if ( aNewValue != m_aProps.aEncryptionKey )
1285 aEvent.PropertyName = rValue.Name;
1286 aEvent.OldValue = uno::makeAny(
1287 m_aProps.aEncryptionKey );
1288 aEvent.NewValue = uno::makeAny( aNewValue );
1290 m_aProps.aEncryptionKey = aNewValue;
1291 nChanged++;
1292 bStore = sal_True;
1293 m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED;
1296 else
1298 aRet[ n ] <<= beans::IllegalTypeException(
1299 OUString(
1300 "Property value has wrong type!" ),
1301 static_cast< cppu::OWeakObject * >( this ) );
1304 else
1306 aRet[ n ] <<= beans::UnknownPropertyException(
1307 OUString(
1308 "EncryptionKey not supported by non-root folder!" ),
1309 static_cast< cppu::OWeakObject * >( this ) );
1312 else
1314 // Not a Core Property! Maybe it's an Additional Core Property?!
1316 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
1318 xAdditionalPropSet = getAdditionalPropertySet( sal_False );
1319 bTriedToGetAdditonalPropSet = sal_True;
1322 if ( xAdditionalPropSet.is() )
1326 uno::Any aOldValue
1327 = xAdditionalPropSet->getPropertyValue( rValue.Name );
1328 if ( aOldValue != rValue.Value )
1330 xAdditionalPropSet->setPropertyValue(
1331 rValue.Name, rValue.Value );
1333 aEvent.PropertyName = rValue.Name;
1334 aEvent.OldValue = aOldValue;
1335 aEvent.NewValue = rValue.Value;
1337 aChanges.getArray()[ nChanged ] = aEvent;
1338 nChanged++;
1341 catch ( beans::UnknownPropertyException const & e )
1343 aRet[ n ] <<= e;
1345 catch ( lang::WrappedTargetException const & e )
1347 aRet[ n ] <<= e;
1349 catch ( beans::PropertyVetoException const & e )
1351 aRet[ n ] <<= e;
1353 catch ( lang::IllegalArgumentException const & e )
1355 aRet[ n ] <<= e;
1358 else
1360 aRet[ n ] <<= uno::Exception(
1361 OUString(
1362 "No property set for storing the value!" ),
1363 static_cast< cppu::OWeakObject * >( this ) );
1368 if ( bExchange )
1370 uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier;
1372 // Assemble new content identifier...
1373 OUString aNewURL = m_aUri.getParentUri();
1374 aNewURL += OUString("/");
1375 aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle );
1376 uno::Reference< ucb::XContentIdentifier > xNewId
1377 = new ::ucbhelper::ContentIdentifier( aNewURL );
1379 aGuard.clear();
1380 if ( exchangeIdentity( xNewId ) )
1382 // Adapt persistent data.
1383 renameData( xOldId, xNewId );
1385 // Adapt Additional Core Properties.
1386 renameAdditionalPropertySet( xOldId->getContentIdentifier(),
1387 xNewId->getContentIdentifier(),
1388 sal_True );
1390 else
1392 // Do not set new title!
1393 aNewTitle = OUString();
1395 // Set error .
1396 aRet[ nTitlePos ] <<= uno::Exception(
1397 OUString("Exchange failed!"),
1398 static_cast< cppu::OWeakObject * >( this ) );
1402 if ( !aNewTitle.isEmpty() )
1404 aEvent.PropertyName = OUString("Title");
1405 aEvent.OldValue = uno::makeAny( m_aProps.aTitle );
1406 aEvent.NewValue = uno::makeAny( aNewTitle );
1408 m_aProps.aTitle = aNewTitle;
1410 aChanges.getArray()[ nChanged ] = aEvent;
1411 nChanged++;
1414 if ( nChanged > 0 )
1416 // Save changes, if content was already made persistent.
1417 if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) ||
1418 ( bStore && ( m_eState == PERSISTENT ) ) )
1420 if ( !storeData( uno::Reference< io::XInputStream >() ) )
1422 uno::Any aProps
1423 = uno::makeAny(
1424 beans::PropertyValue(
1425 OUString(
1426 "Uri"),
1428 uno::makeAny(m_xIdentifier->
1429 getContentIdentifier()),
1430 beans::PropertyState_DIRECT_VALUE));
1431 ucbhelper::cancelCommandExecution(
1432 ucb::IOErrorCode_CANT_WRITE,
1433 uno::Sequence< uno::Any >(&aProps, 1),
1434 xEnv,
1435 OUString(
1436 "Cannot store persistent data!" ),
1437 this );
1438 // Unreachable
1442 aGuard.clear();
1443 aChanges.realloc( nChanged );
1444 notifyPropertiesChange( aChanges );
1447 return aRet;
1450 //=========================================================================
1451 uno::Any Content::open(
1452 const ucb::OpenCommandArgument2& rArg,
1453 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1454 throw( uno::Exception )
1456 if ( rArg.Mode == ucb::OpenMode::ALL ||
1457 rArg.Mode == ucb::OpenMode::FOLDERS ||
1458 rArg.Mode == ucb::OpenMode::DOCUMENTS )
1460 //////////////////////////////////////////////////////////////////
1461 // open command for a folder content
1462 //////////////////////////////////////////////////////////////////
1464 uno::Reference< ucb::XDynamicResultSet > xSet
1465 = new DynamicResultSet( m_xContext, this, rArg, xEnv );
1466 return uno::makeAny( xSet );
1468 else
1470 //////////////////////////////////////////////////////////////////
1471 // open command for a document content
1472 //////////////////////////////////////////////////////////////////
1474 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1475 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1477 // Currently(?) unsupported.
1478 ucbhelper::cancelCommandExecution(
1479 uno::makeAny( ucb::UnsupportedOpenModeException(
1480 OUString(),
1481 static_cast< cppu::OWeakObject * >( this ),
1482 sal_Int16( rArg.Mode ) ) ),
1483 xEnv );
1484 // Unreachable
1487 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1488 if ( xOut.is() )
1490 // PUSH: write data into xOut
1492 uno::Reference< io::XInputStream > xIn = getInputStream();
1493 if ( !xIn.is() )
1495 // No interaction if we are not persistent!
1496 uno::Any aProps
1497 = uno::makeAny(
1498 beans::PropertyValue(
1499 OUString(
1500 "Uri"),
1502 uno::makeAny(m_xIdentifier->
1503 getContentIdentifier()),
1504 beans::PropertyState_DIRECT_VALUE));
1505 ucbhelper::cancelCommandExecution(
1506 ucb::IOErrorCode_CANT_READ,
1507 uno::Sequence< uno::Any >(&aProps, 1),
1508 m_eState == PERSISTENT
1509 ? xEnv
1510 : uno::Reference< ucb::XCommandEnvironment >(),
1511 OUString("Got no data stream!"),
1512 this );
1513 // Unreachable
1518 uno::Sequence< sal_Int8 > aBuffer;
1519 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1521 while ( nRead > 0 )
1523 aBuffer.realloc( nRead );
1524 xOut->writeBytes( aBuffer );
1525 aBuffer.realloc( 0 );
1526 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1529 xOut->closeOutput();
1531 catch ( io::NotConnectedException const & )
1533 // closeOutput, readSomeBytes, writeBytes
1535 catch ( io::BufferSizeExceededException const & )
1537 // closeOutput, readSomeBytes, writeBytes
1539 catch ( io::IOException const & )
1541 // closeOutput, readSomeBytes, writeBytes
1544 else
1546 uno::Reference< io::XActiveDataSink > xDataSink(
1547 rArg.Sink, uno::UNO_QUERY );
1548 if ( xDataSink.is() )
1550 // PULL: wait for client read
1552 uno::Reference< io::XInputStream > xIn = getInputStream();
1553 if ( !xIn.is() )
1555 // No interaction if we are not persistent!
1556 uno::Any aProps
1557 = uno::makeAny(
1558 beans::PropertyValue(
1559 OUString( "Uri"),
1561 uno::makeAny(m_xIdentifier->
1562 getContentIdentifier()),
1563 beans::PropertyState_DIRECT_VALUE));
1564 ucbhelper::cancelCommandExecution(
1565 ucb::IOErrorCode_CANT_READ,
1566 uno::Sequence< uno::Any >(&aProps, 1),
1567 m_eState == PERSISTENT
1568 ? xEnv
1569 : uno::Reference<
1570 ucb::XCommandEnvironment >(),
1571 OUString( "Got no data stream!" ),
1572 this );
1573 // Unreachable
1576 // Done.
1577 xDataSink->setInputStream( xIn );
1579 else
1581 // Note: aOpenCommand.Sink may contain an XStream
1582 // implementation. Support for this type of
1583 // sink is optional...
1584 ucbhelper::cancelCommandExecution(
1585 uno::makeAny(
1586 ucb::UnsupportedDataSinkException(
1587 OUString(),
1588 static_cast< cppu::OWeakObject * >( this ),
1589 rArg.Sink ) ),
1590 xEnv );
1591 // Unreachable
1596 return uno::Any();
1599 //=========================================================================
1600 void Content::insert(
1601 const uno::Reference< io::XInputStream >& xStream,
1602 sal_Int32 nNameClashResolve,
1603 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1604 throw( uno::Exception )
1606 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1608 // Check, if all required properties were set.
1609 if ( isFolder() )
1611 // Required: Title
1613 if ( m_aProps.aTitle.isEmpty() )
1614 m_aProps.aTitle = m_aUri.getName();
1616 else
1618 // Required: rArg.Data
1620 if ( !xStream.is() )
1622 ucbhelper::cancelCommandExecution(
1623 uno::makeAny( ucb::MissingInputStreamException(
1624 OUString(),
1625 static_cast< cppu::OWeakObject * >( this ) ) ),
1626 xEnv );
1627 // Unreachable
1630 // Required: Title
1632 if ( m_aProps.aTitle.isEmpty() )
1633 m_aProps.aTitle = m_aUri.getName();
1636 OUString aNewURL = m_aUri.getParentUri();
1637 if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength())
1638 aNewURL += OUString("/");
1639 aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle );
1640 PackageUri aNewUri( aNewURL );
1642 // Handle possible name clash...
1643 switch ( nNameClashResolve )
1645 // fail.
1646 case ucb::NameClash::ERROR:
1647 if ( hasData( aNewUri ) )
1649 ucbhelper::cancelCommandExecution(
1650 uno::makeAny( ucb::NameClashException(
1651 OUString(),
1652 static_cast< cppu::OWeakObject * >( this ),
1653 task::InteractionClassification_ERROR,
1654 m_aProps.aTitle ) ),
1655 xEnv );
1656 // Unreachable
1658 break;
1660 // replace (possibly) existing object.
1661 case ucb::NameClash::OVERWRITE:
1662 break;
1664 // "invent" a new valid title.
1665 case ucb::NameClash::RENAME:
1666 if ( hasData( aNewUri ) )
1668 sal_Int32 nTry = 0;
1672 OUString aNew = aNewUri.getUri();
1673 aNew += OUString("_");
1674 aNew += OUString::valueOf( ++nTry );
1675 aNewUri.setUri( aNew );
1677 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
1679 if ( nTry == 1000 )
1681 ucbhelper::cancelCommandExecution(
1682 uno::makeAny(
1683 ucb::UnsupportedNameClashException(
1684 OUString( "Unable to resolve name clash!" ),
1685 static_cast< cppu::OWeakObject * >( this ),
1686 nNameClashResolve ) ),
1687 xEnv );
1688 // Unreachable
1690 else
1692 m_aProps.aTitle += OUString("_");
1693 m_aProps.aTitle += OUString::valueOf( nTry );
1696 break;
1698 case ucb::NameClash::KEEP: // deprecated
1699 case ucb::NameClash::ASK:
1700 default:
1701 if ( hasData( aNewUri ) )
1703 ucbhelper::cancelCommandExecution(
1704 uno::makeAny(
1705 ucb::UnsupportedNameClashException(
1706 OUString(),
1707 static_cast< cppu::OWeakObject * >( this ),
1708 nNameClashResolve ) ),
1709 xEnv );
1710 // Unreachable
1712 break;
1715 // Identifier changed?
1716 sal_Bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() );
1718 if ( bNewId )
1720 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1721 m_aUri = aNewUri;
1724 if ( !storeData( xStream ) )
1726 uno::Any aProps
1727 = uno::makeAny(beans::PropertyValue(
1728 OUString( "Uri"),
1730 uno::makeAny(m_xIdentifier->
1731 getContentIdentifier()),
1732 beans::PropertyState_DIRECT_VALUE));
1733 ucbhelper::cancelCommandExecution(
1734 ucb::IOErrorCode_CANT_WRITE,
1735 uno::Sequence< uno::Any >(&aProps, 1),
1736 xEnv,
1737 OUString("Cannot store persistent data!"),
1738 this );
1739 // Unreachable
1742 m_eState = PERSISTENT;
1744 if ( bNewId )
1746 // Take over correct default values from underlying packager...
1747 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1748 loadData( m_pProvider,
1749 m_aUri,
1750 m_aProps,
1751 xXHierarchicalNameAccess );
1753 aGuard.clear();
1754 inserted();
1758 //=========================================================================
1759 void Content::destroy(
1760 sal_Bool bDeletePhysical,
1761 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1762 throw( uno::Exception )
1764 // @@@ take care about bDeletePhysical -> trashcan support
1766 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1768 uno::Reference< ucb::XContent > xThis = this;
1770 // Persistent?
1771 if ( m_eState != PERSISTENT )
1773 ucbhelper::cancelCommandExecution(
1774 uno::makeAny( ucb::UnsupportedCommandException(
1775 OUString( "Not persistent!" ),
1776 static_cast< cppu::OWeakObject * >( this ) ) ),
1777 xEnv );
1778 // Unreachable
1781 m_eState = DEAD;
1783 aGuard.clear();
1784 deleted();
1786 if ( isFolder() )
1788 // Process instanciated children...
1790 ContentRefList aChildren;
1791 queryChildren( aChildren );
1793 ContentRefList::const_iterator it = aChildren.begin();
1794 ContentRefList::const_iterator end = aChildren.end();
1796 while ( it != end )
1798 (*it)->destroy( bDeletePhysical, xEnv );
1799 ++it;
1804 //=========================================================================
1805 void Content::transfer(
1806 const ucb::TransferInfo& rInfo,
1807 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1808 throw( uno::Exception )
1810 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
1812 // Persistent?
1813 if ( m_eState != PERSISTENT )
1815 ucbhelper::cancelCommandExecution(
1816 uno::makeAny( ucb::UnsupportedCommandException(
1817 OUString( "Not persistent!" ),
1818 static_cast< cppu::OWeakObject * >( this ) ) ),
1819 xEnv );
1820 // Unreachable
1823 // Is source a package content?
1824 if ( ( rInfo.SourceURL.isEmpty() ) ||
1825 ( rInfo.SourceURL.compareTo(
1826 m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) )
1828 ucbhelper::cancelCommandExecution(
1829 uno::makeAny( ucb::InteractiveBadTransferURLException(
1830 OUString(),
1831 static_cast< cppu::OWeakObject * >( this ) ) ),
1832 xEnv );
1833 // Unreachable
1836 // Is source not a parent of me / not me?
1837 OUString aId = m_aUri.getParentUri();
1838 aId += OUString("/");
1840 if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1842 if ( aId.compareTo(
1843 rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
1845 uno::Any aProps
1846 = uno::makeAny(beans::PropertyValue(
1847 OUString( "Uri"),
1849 uno::makeAny(rInfo.SourceURL),
1850 beans::PropertyState_DIRECT_VALUE));
1851 ucbhelper::cancelCommandExecution(
1852 ucb::IOErrorCode_RECURSIVE,
1853 uno::Sequence< uno::Any >(&aProps, 1),
1854 xEnv,
1855 OUString( "Target is equal to or is a child of source!" ),
1856 this );
1857 // Unreachable
1861 //////////////////////////////////////////////////////////////////////
1862 // 0) Obtain content object for source.
1863 //////////////////////////////////////////////////////////////////////
1865 uno::Reference< ucb::XContentIdentifier > xId
1866 = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1868 // Note: The static cast is okay here, because its sure that
1869 // m_xProvider is always the PackageContentProvider.
1870 rtl::Reference< Content > xSource;
1874 xSource = static_cast< Content * >(
1875 m_xProvider->queryContent( xId ).get() );
1877 catch ( ucb::IllegalIdentifierException const & )
1879 // queryContent
1882 if ( !xSource.is() )
1884 uno::Any aProps
1885 = uno::makeAny(beans::PropertyValue(
1886 OUString( "Uri"),
1888 uno::makeAny(xId->getContentIdentifier()),
1889 beans::PropertyState_DIRECT_VALUE));
1890 ucbhelper::cancelCommandExecution(
1891 ucb::IOErrorCode_CANT_READ,
1892 uno::Sequence< uno::Any >(&aProps, 1),
1893 xEnv,
1894 OUString( "Cannot instanciate source object!" ),
1895 this );
1896 // Unreachable
1899 //////////////////////////////////////////////////////////////////////
1900 // 1) Create new child content.
1901 //////////////////////////////////////////////////////////////////////
1903 OUString aType = xSource->isFolder()
1904 ? getContentType( m_aUri.getScheme(), sal_True )
1905 : getContentType( m_aUri.getScheme(), sal_False );
1906 ucb::ContentInfo aContentInfo;
1907 aContentInfo.Type = aType;
1908 aContentInfo.Attributes = 0;
1910 // Note: The static cast is okay here, because its sure that
1911 // createNewContent always creates a Content.
1912 rtl::Reference< Content > xTarget
1913 = static_cast< Content * >( createNewContent( aContentInfo ).get() );
1914 if ( !xTarget.is() )
1916 uno::Any aProps
1917 = uno::makeAny(beans::PropertyValue(
1918 OUString( "Folder"),
1920 uno::makeAny(aId),
1921 beans::PropertyState_DIRECT_VALUE));
1922 ucbhelper::cancelCommandExecution(
1923 ucb::IOErrorCode_CANT_CREATE,
1924 uno::Sequence< uno::Any >(&aProps, 1),
1925 xEnv,
1926 OUString( "XContentCreator::createNewContent failed!" ),
1927 this );
1928 // Unreachable
1931 //////////////////////////////////////////////////////////////////////
1932 // 2) Copy data from source content to child content.
1933 //////////////////////////////////////////////////////////////////////
1935 uno::Sequence< beans::Property > aSourceProps
1936 = xSource->getPropertySetInfo( xEnv )->getProperties();
1937 sal_Int32 nCount = aSourceProps.getLength();
1939 if ( nCount )
1941 sal_Bool bHadTitle = rInfo.NewTitle.isEmpty();
1943 // Get all source values.
1944 uno::Reference< sdbc::XRow > xRow
1945 = xSource->getPropertyValues( aSourceProps );
1947 uno::Sequence< beans::PropertyValue > aValues( nCount );
1948 beans::PropertyValue* pValues = aValues.getArray();
1950 const beans::Property* pProps = aSourceProps.getConstArray();
1951 for ( sal_Int32 n = 0; n < nCount; ++n )
1953 const beans::Property& rProp = pProps[ n ];
1954 beans::PropertyValue& rValue = pValues[ n ];
1956 rValue.Name = rProp.Name;
1957 rValue.Handle = rProp.Handle;
1959 if ( !bHadTitle && rProp.Name == "Title" )
1961 // Set new title instead of original.
1962 bHadTitle = sal_True;
1963 rValue.Value <<= rInfo.NewTitle;
1965 else
1966 rValue.Value
1967 = xRow->getObject( n + 1,
1968 uno::Reference<
1969 container::XNameAccess >() );
1971 rValue.State = beans::PropertyState_DIRECT_VALUE;
1973 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1975 // Add Additional Core Property.
1978 xTarget->addProperty( rProp.Name,
1979 rProp.Attributes,
1980 rValue.Value );
1982 catch ( beans::PropertyExistException const & )
1985 catch ( beans::IllegalTypeException const & )
1988 catch ( lang::IllegalArgumentException const & )
1994 // Set target values.
1995 xTarget->setPropertyValues( aValues, xEnv );
1998 //////////////////////////////////////////////////////////////////////
1999 // 3) Commit (insert) child.
2000 //////////////////////////////////////////////////////////////////////
2002 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
2004 //////////////////////////////////////////////////////////////////////
2005 // 4) Transfer (copy) children of source.
2006 //////////////////////////////////////////////////////////////////////
2008 if ( xSource->isFolder() )
2010 uno::Reference< container::XEnumeration > xIter
2011 = xSource->getIterator();
2012 if ( xIter.is() )
2014 while ( xIter->hasMoreElements() )
2018 uno::Reference< container::XNamed > xNamed;
2019 xIter->nextElement() >>= xNamed;
2021 if ( !xNamed.is() )
2023 OSL_FAIL( "Content::transfer - Got no XNamed!" );
2024 break;
2027 OUString aName = xNamed->getName();
2029 if ( aName.isEmpty() )
2031 OSL_FAIL( "Content::transfer - Empty name!" );
2032 break;
2035 OUString aChildId = xId->getContentIdentifier();
2036 if ( ( aChildId.lastIndexOf( '/' ) + 1 )
2037 != aChildId.getLength() )
2038 aChildId += OUString("/");
2040 aChildId += ::ucb_impl::urihelper::encodeSegment( aName );
2042 ucb::TransferInfo aInfo;
2043 aInfo.MoveData = sal_False;
2044 aInfo.NewTitle = OUString();
2045 aInfo.SourceURL = aChildId;
2046 aInfo.NameClash = rInfo.NameClash;
2048 // Transfer child to target.
2049 xTarget->transfer( aInfo, xEnv );
2051 catch ( container::NoSuchElementException const & )
2054 catch ( lang::WrappedTargetException const & )
2061 //////////////////////////////////////////////////////////////////////
2062 // 5) Destroy source ( when moving only ) .
2063 //////////////////////////////////////////////////////////////////////
2065 if ( rInfo.MoveData )
2067 xSource->destroy( sal_True, xEnv );
2069 // Remove all persistent data of source and its children.
2070 if ( !xSource->removeData() )
2072 uno::Any aProps
2073 = uno::makeAny(
2074 beans::PropertyValue(
2075 OUString( "Uri"),
2077 uno::makeAny(
2078 xSource->m_xIdentifier->
2079 getContentIdentifier()),
2080 beans::PropertyState_DIRECT_VALUE));
2081 ucbhelper::cancelCommandExecution(
2082 ucb::IOErrorCode_CANT_WRITE,
2083 uno::Sequence< uno::Any >(&aProps, 1),
2084 xEnv,
2085 OUString( "Cannot remove persistent data of source object!" ),
2086 this );
2087 // Unreachable
2090 // Remove own and all children's Additional Core Properties.
2091 xSource->removeAdditionalPropertySet( sal_True );
2095 //=========================================================================
2096 sal_Bool Content::exchangeIdentity(
2097 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2099 if ( !xNewId.is() )
2100 return sal_False;
2102 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
2104 uno::Reference< ucb::XContent > xThis = this;
2106 // Already persistent?
2107 if ( m_eState != PERSISTENT )
2109 OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
2110 return sal_False;
2113 // Exchange own identitity.
2115 // Fail, if a content with given id already exists.
2116 PackageUri aNewUri( xNewId->getContentIdentifier() );
2117 if ( !hasData( aNewUri ) )
2119 OUString aOldURL = m_xIdentifier->getContentIdentifier();
2121 aGuard.clear();
2122 if ( exchange( xNewId ) )
2124 m_aUri = aNewUri;
2125 if ( isFolder() )
2127 // Process instanciated children...
2129 ContentRefList aChildren;
2130 queryChildren( aChildren );
2132 ContentRefList::const_iterator it = aChildren.begin();
2133 ContentRefList::const_iterator end = aChildren.end();
2135 while ( it != end )
2137 ContentRef xChild = (*it);
2139 // Create new content identifier for the child...
2140 uno::Reference< ucb::XContentIdentifier > xOldChildId
2141 = xChild->getIdentifier();
2142 OUString aOldChildURL
2143 = xOldChildId->getContentIdentifier();
2144 OUString aNewChildURL
2145 = aOldChildURL.replaceAt(
2147 aOldURL.getLength(),
2148 xNewId->getContentIdentifier() );
2149 uno::Reference< ucb::XContentIdentifier > xNewChildId
2150 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
2152 if ( !xChild->exchangeIdentity( xNewChildId ) )
2153 return sal_False;
2155 ++it;
2158 return sal_True;
2162 OSL_FAIL( "Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2163 return sal_False;
2166 //=========================================================================
2167 void Content::queryChildren( ContentRefList& rChildren )
2169 // Obtain a list with a snapshot of all currently instanciated contents
2170 // from provider and extract the contents which are direct children
2171 // of this content.
2173 ::ucbhelper::ContentRefList aAllContents;
2174 m_xProvider->queryExistingContents( aAllContents );
2176 OUString aURL = m_xIdentifier->getContentIdentifier();
2178 OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ),
2179 "Content::queryChildren - Invalid URL!" );
2181 aURL += OUString("/");
2183 sal_Int32 nLen = aURL.getLength();
2185 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
2186 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
2188 while ( it != end )
2190 ::ucbhelper::ContentImplHelperRef xChild = (*it);
2191 OUString aChildURL
2192 = xChild->getIdentifier()->getContentIdentifier();
2194 // Is aURL a prefix of aChildURL?
2195 if ( ( aChildURL.getLength() > nLen ) &&
2196 ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
2198 if ( aChildURL.indexOf( '/', nLen ) == -1 )
2200 // No further slashes. It's a child!
2201 rChildren.push_back(
2202 ContentRef(
2203 static_cast< Content * >( xChild.get() ) ) );
2206 ++it;
2210 //=========================================================================
2211 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage(
2212 const PackageUri& rURI )
2214 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2216 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2217 if ( rURI.getPackage() == m_aUri.getPackage() )
2219 if ( !m_xPackage.is() )
2220 m_xPackage = m_pProvider->createPackage( m_aUri.getPackage(), m_aUri.getParam() );
2222 return m_xPackage;
2225 return m_pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
2228 //=========================================================================
2229 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage()
2231 return getPackage( m_aUri );
2234 //=========================================================================
2235 // static
2236 sal_Bool Content::hasData(
2237 ContentProvider* pProvider,
2238 const PackageUri& rURI,
2239 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2241 rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
2242 if ( !rxPackage.is() )
2243 return sal_False;
2245 return rxPackage->hasByHierarchicalName( rURI.getPath() );
2248 //=========================================================================
2249 sal_Bool Content::hasData( const PackageUri& rURI )
2251 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2253 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2254 if ( rURI.getPackage() == m_aUri.getPackage() )
2256 xPackage = getPackage();
2257 if ( !xPackage.is() )
2258 return sal_False;
2260 return xPackage->hasByHierarchicalName( rURI.getPath() );
2263 return hasData( m_pProvider, rURI, xPackage );
2266 //=========================================================================
2267 //static
2268 sal_Bool Content::loadData(
2269 ContentProvider* pProvider,
2270 const PackageUri& rURI,
2271 ContentProperties& rProps,
2272 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2274 rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() );
2275 if ( !rxPackage.is() )
2276 return sal_False;
2278 if ( rURI.isRootFolder() )
2280 // Properties available only from package
2281 uno::Reference< beans::XPropertySet > xPackagePropSet(
2282 rxPackage, uno::UNO_QUERY );
2284 OSL_ENSURE( xPackagePropSet.is(),
2285 "Content::loadData - "
2286 "Got no XPropertySet interface from package!" );
2288 if ( xPackagePropSet.is() )
2290 // HasEncryptedEntries ( only avalibale at root folder )
2293 uno::Any aHasEncryptedEntries
2294 = xPackagePropSet->getPropertyValue(
2295 OUString( "HasEncryptedEntries" ) );
2296 if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) )
2298 OSL_FAIL( "Content::loadData - "
2299 "Got no HasEncryptedEntries value!" );
2300 return sal_False;
2303 catch ( beans::UnknownPropertyException const & )
2305 OSL_FAIL( "Content::loadData - "
2306 "Got no HasEncryptedEntries value!" );
2307 return sal_False;
2309 catch ( lang::WrappedTargetException const & )
2311 OSL_FAIL( "Content::loadData - "
2312 "Got no HasEncryptedEntries value!" );
2313 return sal_False;
2318 if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) )
2319 return sal_False;
2323 uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() );
2324 if ( aEntry.hasValue() )
2326 uno::Reference< beans::XPropertySet > xPropSet;
2327 aEntry >>= xPropSet;
2329 if ( !xPropSet.is() )
2331 OSL_FAIL( "Content::loadData - Got no XPropertySet interface!" );
2332 return sal_False;
2335 // Title
2336 rProps.aTitle = rURI.getName();
2338 // MediaType
2341 uno::Any aMediaType
2342 = xPropSet->getPropertyValue(
2343 OUString("MediaType") );
2344 if ( !( aMediaType >>= rProps.aMediaType ) )
2346 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2347 return sal_False;
2350 catch ( beans::UnknownPropertyException const & )
2352 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2353 return sal_False;
2355 catch ( lang::WrappedTargetException const & )
2357 OSL_FAIL( "Content::loadData - Got no MediaType value!" );
2358 return sal_False;
2361 uno::Reference< container::XEnumerationAccess > xEnumAccess;
2362 aEntry >>= xEnumAccess;
2364 // ContentType / IsFolder / IsDocument
2365 if ( xEnumAccess.is() )
2367 // folder
2368 rProps.aContentType = getContentType( rURI.getScheme(), sal_True );
2369 rProps.bIsDocument = sal_False;
2370 rProps.bIsFolder = sal_True;
2372 else
2374 // stream
2375 rProps.aContentType = getContentType( rURI.getScheme(), sal_False );
2376 rProps.bIsDocument = sal_True;
2377 rProps.bIsFolder = sal_False;
2380 if ( rProps.bIsDocument )
2382 // Size ( only available for streams )
2385 uno::Any aSize
2386 = xPropSet->getPropertyValue(
2387 OUString("Size") );
2388 if ( !( aSize >>= rProps.nSize ) )
2390 OSL_FAIL( "Content::loadData - Got no Size value!" );
2391 return sal_False;
2394 catch ( beans::UnknownPropertyException const & )
2396 OSL_FAIL( "Content::loadData - Got no Size value!" );
2397 return sal_False;
2399 catch ( lang::WrappedTargetException const & )
2401 OSL_FAIL( "Content::loadData - Got no Size value!" );
2402 return sal_False;
2405 // Compressed ( only available for streams )
2408 uno::Any aCompressed
2409 = xPropSet->getPropertyValue(
2410 OUString("Compressed") );
2411 if ( !( aCompressed >>= rProps.bCompressed ) )
2413 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2414 return sal_False;
2417 catch ( beans::UnknownPropertyException const & )
2419 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2420 return sal_False;
2422 catch ( lang::WrappedTargetException const & )
2424 OSL_FAIL( "Content::loadData - Got no Compressed value!" );
2425 return sal_False;
2428 // Encrypted ( only available for streams )
2431 uno::Any aEncrypted
2432 = xPropSet->getPropertyValue(
2433 OUString("Encrypted") );
2434 if ( !( aEncrypted >>= rProps.bEncrypted ) )
2436 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2437 return sal_False;
2440 catch ( beans::UnknownPropertyException const & )
2442 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2443 return sal_False;
2445 catch ( lang::WrappedTargetException const & )
2447 OSL_FAIL( "Content::loadData - Got no Encrypted value!" );
2448 return sal_False;
2451 return sal_True;
2454 catch ( container::NoSuchElementException const & )
2456 // getByHierarchicalName
2459 return sal_False;
2462 //=========================================================================
2463 sal_Bool Content::renameData(
2464 const uno::Reference< ucb::XContentIdentifier >& xOldId,
2465 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2467 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2469 PackageUri aURI( xOldId->getContentIdentifier() );
2470 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(
2471 aURI );
2472 if ( !xNA.is() )
2473 return sal_False;
2475 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2476 return sal_False;
2480 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2481 uno::Reference< container::XNamed > xNamed;
2482 aEntry >>= xNamed;
2484 if ( !xNamed.is() )
2486 OSL_FAIL( "Content::renameData - Got no XNamed interface!" );
2487 return sal_False;
2490 PackageUri aNewURI( xNewId->getContentIdentifier() );
2492 // No success indicator!? No return value / exceptions specified.
2493 xNamed->setName( aNewURI.getName() );
2495 return sal_True;
2497 catch ( container::NoSuchElementException const & )
2499 // getByHierarchicalName
2502 return sal_False;
2505 //=========================================================================
2506 sal_Bool Content::storeData( const uno::Reference< io::XInputStream >& xStream )
2508 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2510 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2511 if ( !xNA.is() )
2512 return sal_False;
2514 uno::Reference< beans::XPropertySet > xPackagePropSet(
2515 xNA, uno::UNO_QUERY );
2516 OSL_ENSURE( xPackagePropSet.is(),
2517 "Content::storeData - "
2518 "Got no XPropertySet interface from package!" );
2520 if ( !xPackagePropSet.is() )
2521 return sal_False;
2523 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2525 if ( m_aUri.isRootFolder() )
2527 // Property available only from package and from streams (see below)
2530 xPackagePropSet->setPropertyValue(
2531 OUString("EncryptionKey"),
2532 uno::makeAny( m_aProps.aEncryptionKey ) );
2533 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2535 catch ( beans::UnknownPropertyException const & )
2537 // setPropertyValue
2539 catch ( beans::PropertyVetoException const & )
2541 // setPropertyValue
2543 catch ( lang::IllegalArgumentException const & )
2545 // setPropertyValue
2547 catch ( lang::WrappedTargetException const & )
2549 // setPropertyValue
2554 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2556 // if ( !bCreate )
2557 // return sal_True;
2561 // Create new resource...
2562 uno::Reference< lang::XSingleServiceFactory > xFac(
2563 xNA, uno::UNO_QUERY );
2564 if ( !xFac.is() )
2566 OSL_FAIL( "Content::storeData - "
2567 "Got no XSingleServiceFactory interface!" );
2568 return sal_False;
2571 uno::Sequence< uno::Any > aArgs( 1 );
2572 aArgs[ 0 ] <<= isFolder();
2574 uno::Reference< uno::XInterface > xNew
2575 = xFac->createInstanceWithArguments( aArgs );
2577 if ( !xNew.is() )
2579 OSL_FAIL( "Content::storeData - createInstance failed!" );
2580 return sal_False;
2583 PackageUri aParentUri( getParentURL() );
2584 uno::Any aEntry
2585 = xNA->getByHierarchicalName( aParentUri.getPath() );
2586 uno::Reference< container::XNameContainer > xParentContainer;
2587 aEntry >>= xParentContainer;
2589 if ( !xParentContainer.is() )
2591 OSL_FAIL( "Content::storeData - "
2592 "Got no XNameContainer interface!" );
2593 return sal_False;
2596 xParentContainer->insertByName( m_aProps.aTitle,
2597 uno::makeAny( xNew ) );
2599 catch ( lang::IllegalArgumentException const & )
2601 // insertByName
2602 OSL_FAIL( "Content::storeData - insertByName failed!" );
2603 return sal_False;
2605 catch ( uno::RuntimeException const & )
2607 throw;
2609 catch ( container::ElementExistException const & )
2611 // insertByName
2612 OSL_FAIL( "Content::storeData - insertByName failed!" );
2613 return sal_False;
2615 catch ( lang::WrappedTargetException const & )
2617 // insertByName
2618 OSL_FAIL( "Content::storeData - insertByName failed!" );
2619 return sal_False;
2621 catch ( container::NoSuchElementException const & )
2623 // getByHierarchicalName
2624 OSL_FAIL( "Content::storeData - getByHierarchicalName failed!" );
2625 return sal_False;
2627 catch ( uno::Exception const & )
2629 // createInstanceWithArguments
2630 OSL_FAIL( "Content::storeData - Error!" );
2631 return sal_False;
2635 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2636 return sal_False;
2640 uno::Reference< beans::XPropertySet > xPropSet;
2641 xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet;
2643 if ( !xPropSet.is() )
2645 OSL_FAIL( "Content::storeData - Got no XPropertySet interface!" );
2646 return sal_False;
2649 //////////////////////////////////////////////////////////////////
2650 // Store property values...
2651 //////////////////////////////////////////////////////////////////
2653 if ( m_nModifiedProps & MEDIATYPE_MODIFIED )
2655 xPropSet->setPropertyValue(
2656 OUString("MediaType"),
2657 uno::makeAny( m_aProps.aMediaType ) );
2658 m_nModifiedProps &= ~MEDIATYPE_MODIFIED;
2661 if ( m_nModifiedProps & COMPRESSED_MODIFIED )
2663 if ( !isFolder() )
2664 xPropSet->setPropertyValue(
2665 OUString("Compressed"),
2666 uno::makeAny( m_aProps.bCompressed ) );
2668 m_nModifiedProps &= ~COMPRESSED_MODIFIED;
2671 if ( m_nModifiedProps & ENCRYPTED_MODIFIED )
2673 if ( !isFolder() )
2674 xPropSet->setPropertyValue(
2675 OUString("Encrypted"),
2676 uno::makeAny( m_aProps.bEncrypted ) );
2678 m_nModifiedProps &= ~ENCRYPTED_MODIFIED;
2681 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED )
2683 if ( !isFolder() )
2684 xPropSet->setPropertyValue(
2685 OUString("EncryptionKey"),
2686 uno::makeAny( m_aProps.aEncryptionKey ) );
2688 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED;
2691 //////////////////////////////////////////////////////////////////
2692 // Store data stream...
2693 //////////////////////////////////////////////////////////////////
2695 if ( xStream.is() && !isFolder() )
2697 uno::Reference< io::XActiveDataSink > xSink(
2698 xPropSet, uno::UNO_QUERY );
2700 if ( !xSink.is() )
2702 OSL_FAIL( "Content::storeData - "
2703 "Got no XActiveDataSink interface!" );
2704 return sal_False;
2707 xSink->setInputStream( xStream );
2710 return sal_True;
2712 catch ( container::NoSuchElementException const & )
2714 // getByHierarchicalName
2716 catch ( beans::UnknownPropertyException const & )
2718 // setPropertyValue
2720 catch ( beans::PropertyVetoException const & )
2722 // setPropertyValue
2724 catch ( lang::IllegalArgumentException const & )
2726 // setPropertyValue
2728 catch ( lang::WrappedTargetException const & )
2730 // setPropertyValue
2733 OSL_FAIL( "Content::storeData - Error!" );
2734 return sal_False;
2737 //=========================================================================
2738 sal_Bool Content::removeData()
2740 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2742 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2743 if ( !xNA.is() )
2744 return sal_False;
2746 PackageUri aParentUri( getParentURL() );
2747 if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) )
2748 return sal_False;
2752 uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() );
2753 uno::Reference< container::XNameContainer > xContainer;
2754 aEntry >>= xContainer;
2756 if ( !xContainer.is() )
2758 OSL_FAIL( "Content::removeData - "
2759 "Got no XNameContainer interface!" );
2760 return sal_False;
2763 xContainer->removeByName( m_aUri.getName() );
2764 return sal_True;
2766 catch ( container::NoSuchElementException const & )
2768 // getByHierarchicalName, removeByName
2770 catch ( lang::WrappedTargetException const & )
2772 // removeByName
2775 OSL_FAIL( "Content::removeData - Error!" );
2776 return sal_False;
2779 //=========================================================================
2780 sal_Bool Content::flushData()
2782 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2784 // Note: XChangesBatch is only implemented by the package itself, not
2785 // by the single entries. Maybe this has to change...
2787 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2788 if ( !xNA.is() )
2789 return sal_False;
2791 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2792 if ( !xBatch.is() )
2794 OSL_FAIL( "Content::flushData - Got no XChangesBatch interface!" );
2795 return sal_False;
2800 xBatch->commitChanges();
2801 return sal_True;
2803 catch ( lang::WrappedTargetException const & )
2807 OSL_FAIL( "Content::flushData - Error!" );
2808 return sal_False;
2811 //=========================================================================
2812 uno::Reference< io::XInputStream > Content::getInputStream()
2814 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2816 uno::Reference< io::XInputStream > xStream;
2817 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2818 if ( !xNA.is() )
2819 return xStream;
2821 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2822 return xStream;
2826 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2827 uno::Reference< io::XActiveDataSink > xSink;
2828 aEntry >>= xSink;
2830 if ( !xSink.is() )
2832 OSL_FAIL( "Content::getInputStream - "
2833 "Got no XActiveDataSink interface!" );
2834 return xStream;
2837 xStream = xSink->getInputStream();
2839 OSL_ENSURE( xStream.is(),
2840 "Content::getInputStream - Got no stream!" );
2842 catch ( container::NoSuchElementException const & )
2844 // getByHierarchicalName
2847 return xStream;
2850 //=========================================================================
2851 uno::Reference< container::XEnumeration > Content::getIterator()
2853 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2855 uno::Reference< container::XEnumeration > xIter;
2856 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage();
2857 if ( !xNA.is() )
2858 return xIter;
2860 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) )
2861 return xIter;
2865 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() );
2866 uno::Reference< container::XEnumerationAccess > xIterFac;
2867 aEntry >>= xIterFac;
2869 if ( !xIterFac.is() )
2871 OSL_FAIL( "Content::getIterator - "
2872 "Got no XEnumerationAccess interface!" );
2873 return xIter;
2876 xIter = xIterFac->createEnumeration();
2878 OSL_ENSURE( xIter.is(),
2879 "Content::getIterator - Got no iterator!" );
2881 catch ( container::NoSuchElementException const & )
2883 // getByHierarchicalName
2886 return xIter;
2889 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */