LCOV - code coverage report
Current view: top level - ucb/source/ucp/tdoc - tdoc_content.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 977 0.0 %
Date: 2014-04-14 Functions: 0 51 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : /**************************************************************************
      22             :                                 TODO
      23             :  **************************************************************************
      24             : 
      25             :  *************************************************************************/
      26             : 
      27             : #include "osl/diagnose.h"
      28             : #include "osl/doublecheckedlocking.h"
      29             : #include "rtl/ustrbuf.hxx"
      30             : 
      31             : #include "com/sun/star/beans/PropertyAttribute.hpp"
      32             : #include "com/sun/star/beans/PropertyValue.hpp"
      33             : #include "com/sun/star/beans/XPropertySet.hpp"
      34             : #include "com/sun/star/embed/ElementModes.hpp"
      35             : #include "com/sun/star/embed/XStorage.hpp"
      36             : #include "com/sun/star/embed/XTransactedObject.hpp"
      37             : #include "com/sun/star/io/XActiveDataSink.hpp"
      38             : #include "com/sun/star/io/XActiveDataStreamer.hpp"
      39             : #include "com/sun/star/lang/IllegalAccessException.hpp"
      40             : #include "com/sun/star/sdbc/XRow.hpp"
      41             : #include "com/sun/star/ucb/ContentAction.hpp"
      42             : #include "com/sun/star/ucb/ContentInfoAttribute.hpp"
      43             : #include "com/sun/star/ucb/InsertCommandArgument.hpp"
      44             : #include "com/sun/star/ucb/InteractiveBadTransferURLException.hpp"
      45             : #include "com/sun/star/ucb/MissingInputStreamException.hpp"
      46             : #include "com/sun/star/ucb/MissingPropertiesException.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/UnsupportedCommandException.hpp"
      53             : #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
      54             : #include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
      55             : #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
      56             : #include "com/sun/star/ucb/XCommandInfo.hpp"
      57             : #include "com/sun/star/ucb/XPersistentPropertySet.hpp"
      58             : 
      59             : #include "comphelper/processfactory.hxx"
      60             : #include "ucbhelper/cancelcommandexecution.hxx"
      61             : #include "ucbhelper/contentidentifier.hxx"
      62             : #include "ucbhelper/propertyvalueset.hxx"
      63             : 
      64             : #include "tdoc_content.hxx"
      65             : #include "tdoc_resultset.hxx"
      66             : #include "tdoc_passwordrequest.hxx"
      67             : 
      68             : #include "../inc/urihelper.hxx"
      69             : 
      70             : using namespace com::sun::star;
      71             : using namespace tdoc_ucp;
      72             : 
      73             : 
      74           0 : static ContentType lcl_getContentType( const OUString & rType )
      75             : {
      76           0 :     if ( rType == TDOC_ROOT_CONTENT_TYPE )
      77           0 :         return ROOT;
      78           0 :     else if ( rType == TDOC_DOCUMENT_CONTENT_TYPE )
      79           0 :         return DOCUMENT;
      80           0 :     else if ( rType == TDOC_FOLDER_CONTENT_TYPE )
      81           0 :         return FOLDER;
      82           0 :     else if ( rType == TDOC_STREAM_CONTENT_TYPE )
      83           0 :         return STREAM;
      84             :     else
      85             :     {
      86             :         OSL_FAIL( "Content::Content - unsupported content type string" );
      87           0 :         return STREAM;
      88             :     }
      89             : }
      90             : 
      91             : 
      92             : 
      93             : 
      94             : // Content Implementation.
      95             : 
      96             : 
      97             : 
      98             : 
      99             : // static ( "virtual" ctor )
     100           0 : Content* Content::create(
     101             :             const uno::Reference< uno::XComponentContext >& rxContext,
     102             :             ContentProvider* pProvider,
     103             :             const uno::Reference< ucb::XContentIdentifier >& Identifier )
     104             : {
     105             :     // Fail, if resource does not exist.
     106           0 :     ContentProperties aProps;
     107           0 :     if ( !Content::loadData( pProvider,
     108           0 :                              Uri( Identifier->getContentIdentifier() ),
     109           0 :                              aProps ) )
     110           0 :         return 0;
     111             : 
     112           0 :     return new Content( rxContext, pProvider, Identifier, aProps );
     113             : }
     114             : 
     115             : 
     116             : // static ( "virtual" ctor )
     117           0 : Content* Content::create(
     118             :             const uno::Reference< uno::XComponentContext >& rxContext,
     119             :             ContentProvider* pProvider,
     120             :             const uno::Reference< ucb::XContentIdentifier >& Identifier,
     121             :             const ucb::ContentInfo& Info )
     122             : {
     123           0 :     if ( Info.Type.isEmpty() )
     124           0 :         return 0;
     125             : 
     126           0 :     if ( Info.Type != TDOC_FOLDER_CONTENT_TYPE && Info.Type != TDOC_STREAM_CONTENT_TYPE )
     127             :     {
     128             :         OSL_FAIL( "Content::create - unsupported content type!" );
     129           0 :         return 0;
     130             :     }
     131             : 
     132           0 :     return new Content( rxContext, pProvider, Identifier, Info );
     133             : }
     134             : 
     135             : 
     136           0 : Content::Content(
     137             :             const uno::Reference< uno::XComponentContext > & rxContext,
     138             :             ContentProvider * pProvider,
     139             :             const uno::Reference< ucb::XContentIdentifier > & Identifier,
     140             :             const ContentProperties & rProps )
     141             : : ContentImplHelper( rxContext, pProvider, Identifier ),
     142             :   m_aProps( rProps ),
     143             :   m_eState( PERSISTENT ),
     144           0 :   m_pProvider( pProvider )
     145             : {
     146           0 : }
     147             : 
     148             : 
     149             : // ctor for a content just created via XContentCreator::createNewContent()
     150           0 : Content::Content(
     151             :             const uno::Reference< uno::XComponentContext >& rxContext,
     152             :             ContentProvider* pProvider,
     153             :             const uno::Reference< ucb::XContentIdentifier >& Identifier,
     154             :             const ucb::ContentInfo& Info )
     155             :   : ContentImplHelper( rxContext, pProvider, Identifier ),
     156           0 :   m_aProps( lcl_getContentType( Info.Type ), OUString() ), // no Title (yet)
     157             :   m_eState( TRANSIENT ),
     158           0 :   m_pProvider( pProvider )
     159             : {
     160           0 : }
     161             : 
     162             : 
     163             : // virtual
     164           0 : Content::~Content()
     165             : {
     166           0 : }
     167             : 
     168             : 
     169             : 
     170             : // XInterface methods.
     171             : 
     172             : 
     173             : 
     174             : // virtual
     175           0 : void SAL_CALL Content::acquire()
     176             :     throw( )
     177             : {
     178           0 :     ContentImplHelper::acquire();
     179           0 : }
     180             : 
     181             : 
     182             : // virtual
     183           0 : void SAL_CALL Content::release()
     184             :     throw( )
     185             : {
     186           0 :     ContentImplHelper::release();
     187           0 : }
     188             : 
     189             : 
     190             : // virtual
     191           0 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
     192             :     throw ( uno::RuntimeException, std::exception )
     193             : {
     194           0 :     uno::Any aRet = ContentImplHelper::queryInterface( rType );
     195             : 
     196           0 :     if ( !aRet.hasValue() )
     197             :     {
     198           0 :         aRet = cppu::queryInterface(
     199           0 :                 rType, static_cast< ucb::XContentCreator * >( this ) );
     200           0 :         if ( aRet.hasValue() )
     201             :         {
     202           0 :             if ( !m_aProps.isContentCreator() )
     203           0 :                 return uno::Any();
     204             :         }
     205             :     }
     206             : 
     207           0 :     return aRet;
     208             : }
     209             : 
     210             : 
     211             : 
     212             : // XTypeProvider methods.
     213             : 
     214             : 
     215             : 
     216           0 : XTYPEPROVIDER_COMMON_IMPL( Content );
     217             : 
     218             : 
     219             : // virtual
     220           0 : uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
     221             :     throw( uno::RuntimeException, std::exception )
     222             : {
     223           0 :     cppu::OTypeCollection * pCollection = 0;
     224             : 
     225           0 :     if ( m_aProps.isContentCreator() )
     226             :     {
     227             :         static cppu::OTypeCollection* pFolderTypes = 0;
     228             : 
     229           0 :         pCollection = pFolderTypes;
     230           0 :         if ( !pCollection )
     231             :         {
     232           0 :             osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
     233             : 
     234           0 :             pCollection = pFolderTypes;
     235           0 :             if ( !pCollection )
     236             :             {
     237             :                 static cppu::OTypeCollection aCollection(
     238           0 :                     CPPU_TYPE_REF( lang::XTypeProvider ),
     239           0 :                     CPPU_TYPE_REF( lang::XServiceInfo ),
     240           0 :                     CPPU_TYPE_REF( lang::XComponent ),
     241           0 :                     CPPU_TYPE_REF( ucb::XContent ),
     242           0 :                     CPPU_TYPE_REF( ucb::XCommandProcessor ),
     243           0 :                     CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
     244           0 :                     CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
     245           0 :                     CPPU_TYPE_REF( beans::XPropertyContainer ),
     246           0 :                     CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
     247           0 :                     CPPU_TYPE_REF( container::XChild ),
     248           0 :                     CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
     249           0 :                 pCollection = &aCollection;
     250             :                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     251           0 :                 pFolderTypes = pCollection;
     252           0 :             }
     253             :         }
     254             :         else {
     255             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     256             :         }
     257             :     }
     258             :     else
     259             :     {
     260             :         static cppu::OTypeCollection* pDocumentTypes = 0;
     261             : 
     262           0 :         pCollection = pDocumentTypes;
     263           0 :         if ( !pCollection )
     264             :         {
     265           0 :             osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
     266             : 
     267           0 :             pCollection = pDocumentTypes;
     268           0 :             if ( !pCollection )
     269             :             {
     270             :                 static cppu::OTypeCollection aCollection(
     271           0 :                     CPPU_TYPE_REF( lang::XTypeProvider ),
     272           0 :                     CPPU_TYPE_REF( lang::XServiceInfo ),
     273           0 :                     CPPU_TYPE_REF( lang::XComponent ),
     274           0 :                     CPPU_TYPE_REF( ucb::XContent ),
     275           0 :                     CPPU_TYPE_REF( ucb::XCommandProcessor ),
     276           0 :                     CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
     277           0 :                     CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
     278           0 :                     CPPU_TYPE_REF( beans::XPropertyContainer ),
     279           0 :                     CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
     280           0 :                     CPPU_TYPE_REF( container::XChild ) );
     281           0 :                 pCollection = &aCollection;
     282             :                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     283           0 :                 pDocumentTypes = pCollection;
     284           0 :             }
     285             :         }
     286             :         else {
     287             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     288             :         }
     289             :     }
     290             : 
     291           0 :     return (*pCollection).getTypes();
     292             : }
     293             : 
     294             : 
     295             : 
     296             : // XServiceInfo methods.
     297             : 
     298             : 
     299             : 
     300             : // virtual
     301           0 : OUString SAL_CALL Content::getImplementationName()
     302             :     throw( uno::RuntimeException, std::exception )
     303             : {
     304           0 :     return OUString( "com.sun.star.comp.ucb.TransientDocumentsContent" );
     305             : }
     306             : 
     307             : 
     308             : // virtual
     309           0 : uno::Sequence< OUString > SAL_CALL Content::getSupportedServiceNames()
     310             :     throw( uno::RuntimeException, std::exception )
     311             : {
     312           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     313             : 
     314           0 :     uno::Sequence< OUString > aSNS( 1 );
     315             : 
     316           0 :     if ( m_aProps.getType() == STREAM )
     317           0 :         aSNS.getArray()[ 0 ] = TDOC_STREAM_CONTENT_SERVICE_NAME;
     318           0 :     else if ( m_aProps.getType() == FOLDER )
     319           0 :         aSNS.getArray()[ 0 ] = TDOC_FOLDER_CONTENT_SERVICE_NAME;
     320           0 :     else if ( m_aProps.getType() == DOCUMENT )
     321           0 :         aSNS.getArray()[ 0 ] = TDOC_DOCUMENT_CONTENT_SERVICE_NAME;
     322             :     else
     323           0 :         aSNS.getArray()[ 0 ] = TDOC_ROOT_CONTENT_SERVICE_NAME;
     324             : 
     325           0 :     return aSNS;
     326             : }
     327             : 
     328             : 
     329             : 
     330             : // XContent methods.
     331             : 
     332             : 
     333             : 
     334             : // virtual
     335           0 : OUString SAL_CALL Content::getContentType()
     336             :     throw( uno::RuntimeException, std::exception )
     337             : {
     338           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     339           0 :     return m_aProps.getContentType();
     340             : }
     341             : 
     342             : 
     343             : // virtual
     344             : uno::Reference< ucb::XContentIdentifier > SAL_CALL
     345           0 : Content::getIdentifier()
     346             :     throw( uno::RuntimeException, std::exception )
     347             : {
     348             :     {
     349           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     350             : 
     351             :         // Transient?
     352           0 :         if ( m_eState == TRANSIENT )
     353             :         {
     354             :             // Transient contents have no identifier.
     355           0 :             return uno::Reference< ucb::XContentIdentifier >();
     356           0 :         }
     357             :     }
     358           0 :     return ContentImplHelper::getIdentifier();
     359             : }
     360             : 
     361             : 
     362             : 
     363             : // XCommandProcessor methods.
     364             : 
     365             : 
     366             : 
     367             : // virtual
     368           0 : uno::Any SAL_CALL Content::execute(
     369             :         const ucb::Command& aCommand,
     370             :         sal_Int32 /*CommandId*/,
     371             :         const uno::Reference< ucb::XCommandEnvironment >& Environment )
     372             :     throw( uno::Exception,
     373             :            ucb::CommandAbortedException,
     374             :            uno::RuntimeException, std::exception )
     375             : {
     376           0 :     uno::Any aRet;
     377             : 
     378           0 :     if ( aCommand.Name == "getPropertyValues" )
     379             :     {
     380             : 
     381             :         // getPropertyValues
     382             : 
     383             : 
     384           0 :         uno::Sequence< beans::Property > Properties;
     385           0 :         if ( !( aCommand.Argument >>= Properties ) )
     386             :         {
     387             :             ucbhelper::cancelCommandExecution(
     388             :                 uno::makeAny( lang::IllegalArgumentException(
     389             :                                     OUString( "Wrong argument type!" ),
     390             :                                     static_cast< cppu::OWeakObject * >( this ),
     391             :                                     -1 ) ),
     392           0 :                 Environment );
     393             :             // Unreachable
     394             :         }
     395             : 
     396           0 :         aRet <<= getPropertyValues( Properties );
     397             :     }
     398           0 :     else if ( aCommand.Name == "setPropertyValues" )
     399             :     {
     400             : 
     401             :         // setPropertyValues
     402             : 
     403             : 
     404           0 :         uno::Sequence< beans::PropertyValue > aProperties;
     405           0 :         if ( !( aCommand.Argument >>= aProperties ) )
     406             :         {
     407             :             ucbhelper::cancelCommandExecution(
     408             :                 uno::makeAny( lang::IllegalArgumentException(
     409             :                                     OUString( "Wrong argument type!" ),
     410             :                                     static_cast< cppu::OWeakObject * >( this ),
     411             :                                     -1 ) ),
     412           0 :                 Environment );
     413             :             // Unreachable
     414             :         }
     415             : 
     416           0 :         if ( !aProperties.getLength() )
     417             :         {
     418             :             ucbhelper::cancelCommandExecution(
     419             :                 uno::makeAny( lang::IllegalArgumentException(
     420             :                                     OUString( "No properties!" ),
     421             :                                     static_cast< cppu::OWeakObject * >( this ),
     422             :                                     -1 ) ),
     423           0 :                 Environment );
     424             :             // Unreachable
     425             :         }
     426             : 
     427           0 :         aRet <<= setPropertyValues( aProperties, Environment );
     428             :     }
     429           0 :     else if ( aCommand.Name == "getPropertySetInfo" )
     430             :     {
     431             : 
     432             :         // getPropertySetInfo
     433             : 
     434             : 
     435           0 :         aRet <<= getPropertySetInfo( Environment );
     436             :     }
     437           0 :     else if ( aCommand.Name == "getCommandInfo" )
     438             :     {
     439             : 
     440             :         // getCommandInfo
     441             : 
     442             : 
     443           0 :         aRet <<= getCommandInfo( Environment );
     444             :     }
     445           0 :     else if ( aCommand.Name == "open" )
     446             :     {
     447             : 
     448             :         // open
     449             : 
     450             : 
     451           0 :         ucb::OpenCommandArgument2 aOpenCommand;
     452           0 :         if ( !( aCommand.Argument >>= aOpenCommand ) )
     453             :         {
     454             :             ucbhelper::cancelCommandExecution(
     455             :                 uno::makeAny( lang::IllegalArgumentException(
     456             :                                     OUString( "Wrong argument type!" ),
     457             :                                     static_cast< cppu::OWeakObject * >( this ),
     458             :                                     -1 ) ),
     459           0 :                 Environment );
     460             :             // Unreachable
     461             :         }
     462             : 
     463           0 :         aRet = open( aOpenCommand, Environment );
     464             :     }
     465           0 :     else if ( aCommand.Name == "insert" )
     466             :     {
     467             : 
     468             :         // insert ( Supported by folders and streams only )
     469             : 
     470             : 
     471           0 :         ContentType eType = m_aProps.getType();
     472           0 :         if ( ( eType != FOLDER ) && ( eType != STREAM ) )
     473             :         {
     474             :             ucbhelper::cancelCommandExecution(
     475             :                 uno::makeAny( ucb::UnsupportedCommandException(
     476             :                                 OUString( "insert command only supported by "
     477             :                                         "folders and streams!"  ),
     478             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
     479           0 :                 Environment );
     480             :             // Unreachable
     481             :         }
     482             : 
     483             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
     484           0 :         if ( eType == STREAM )
     485             :         {
     486           0 :             Uri aUri( m_xIdentifier->getContentIdentifier() );
     487           0 :             Uri aParentUri( aUri.getParentUri() );
     488           0 :             if ( aParentUri.isDocument() )
     489             :             {
     490             :                 ucbhelper::cancelCommandExecution(
     491             :                     uno::makeAny( ucb::UnsupportedCommandException(
     492             :                                     OUString( "insert command not supported by "
     493             :                                             "streams that are direct children "
     494             :                                             "of document root!"  ),
     495             :                                     static_cast< cppu::OWeakObject * >(
     496             :                                         this ) ) ),
     497           0 :                     Environment );
     498             :                 // Unreachable
     499           0 :             }
     500             :         }
     501             : #endif
     502           0 :         ucb::InsertCommandArgument aArg;
     503           0 :         if ( !( aCommand.Argument >>= aArg ) )
     504             :         {
     505             :             ucbhelper::cancelCommandExecution(
     506             :                 uno::makeAny( lang::IllegalArgumentException(
     507             :                                     OUString( "Wrong argument type!" ),
     508             :                                     static_cast< cppu::OWeakObject * >( this ),
     509             :                                     -1 ) ),
     510           0 :                 Environment );
     511             :             // Unreachable
     512             :         }
     513             : 
     514             :         sal_Int32 nNameClash = aArg.ReplaceExisting
     515             :                              ? ucb::NameClash::OVERWRITE
     516           0 :                              : ucb::NameClash::ERROR;
     517           0 :         insert( aArg.Data, nNameClash, Environment );
     518             :     }
     519           0 :     else if ( aCommand.Name == "delete" )
     520             :     {
     521             : 
     522             :         // delete ( Supported by folders and streams only )
     523             : 
     524             : 
     525             :         {
     526           0 :             osl::MutexGuard aGuard( m_aMutex );
     527             : 
     528           0 :             ContentType eType = m_aProps.getType();
     529           0 :             if ( ( eType != FOLDER ) && ( eType != STREAM ) )
     530             :             {
     531             :                 ucbhelper::cancelCommandExecution(
     532             :                     uno::makeAny( ucb::UnsupportedCommandException(
     533             :                                     OUString( "delete command only supported by "
     534             :                                             "folders and streams!"  ),
     535             :                                     static_cast< cppu::OWeakObject * >(
     536             :                                         this ) ) ),
     537           0 :                     Environment );
     538             :                 // Unreachable
     539           0 :             }
     540             :         }
     541             : 
     542           0 :         sal_Bool bDeletePhysical = sal_False;
     543           0 :         aCommand.Argument >>= bDeletePhysical;
     544           0 :         destroy( bDeletePhysical, Environment );
     545             : 
     546             :         // Remove own and all children's persistent data.
     547           0 :         if ( !removeData() )
     548             :         {
     549             :             uno::Any aProps
     550             :                 = uno::makeAny(
     551             :                          beans::PropertyValue(
     552             :                              OUString( "Uri"),
     553             :                              -1,
     554           0 :                              uno::makeAny(m_xIdentifier->
     555           0 :                                               getContentIdentifier()),
     556           0 :                              beans::PropertyState_DIRECT_VALUE));
     557             :             ucbhelper::cancelCommandExecution(
     558             :                 ucb::IOErrorCode_CANT_WRITE,
     559             :                 uno::Sequence< uno::Any >(&aProps, 1),
     560             :                 Environment,
     561             :                 OUString( "Cannot remove persistent data!" ),
     562           0 :                 this );
     563             :             // Unreachable
     564             :         }
     565             : 
     566             :         // Remove own and all children's Additional Core Properties.
     567           0 :         removeAdditionalPropertySet( true );
     568             :     }
     569           0 :     else if ( aCommand.Name == "transfer" )
     570             :     {
     571             : 
     572             :         // transfer ( Supported by document and folders only )
     573             : 
     574             : 
     575             :         {
     576           0 :             osl::MutexGuard aGuard( m_aMutex );
     577             : 
     578           0 :             ContentType eType = m_aProps.getType();
     579           0 :             if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
     580             :             {
     581             :                 ucbhelper::cancelCommandExecution(
     582             :                     uno::makeAny( ucb::UnsupportedCommandException(
     583             :                                     OUString( "transfer command only supported "
     584             :                                             "by folders and documents!"  ),
     585             :                                     static_cast< cppu::OWeakObject * >(
     586             :                                         this ) ) ),
     587           0 :                     Environment );
     588             :                 // Unreachable
     589           0 :             }
     590             :         }
     591             : 
     592           0 :         ucb::TransferInfo aInfo;
     593           0 :         if ( !( aCommand.Argument >>= aInfo ) )
     594             :         {
     595             :             OSL_FAIL( "Wrong argument type!" );
     596             :             ucbhelper::cancelCommandExecution(
     597             :                 uno::makeAny( lang::IllegalArgumentException(
     598             :                                     OUString( "Wrong argument type!" ),
     599             :                                     static_cast< cppu::OWeakObject * >( this ),
     600             :                                     -1 ) ),
     601           0 :                 Environment );
     602             :             // Unreachable
     603             :         }
     604             : 
     605           0 :         transfer( aInfo, Environment );
     606             :     }
     607           0 :     else if ( aCommand.Name == "createNewContent" )
     608             :     {
     609             : 
     610             :         // createNewContent ( Supported by document and folders only )
     611             : 
     612             : 
     613             :         {
     614           0 :             osl::MutexGuard aGuard( m_aMutex );
     615             : 
     616           0 :             ContentType eType = m_aProps.getType();
     617           0 :             if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
     618             :             {
     619             :                 ucbhelper::cancelCommandExecution(
     620             :                     uno::makeAny( ucb::UnsupportedCommandException(
     621             :                                     OUString( "createNewContent command only "
     622             :                                             "supported by folders and "
     623             :                                             "documents!"  ),
     624             :                                     static_cast< cppu::OWeakObject * >(
     625             :                                         this ) ) ),
     626           0 :                     Environment );
     627             :                 // Unreachable
     628           0 :             }
     629             :         }
     630             : 
     631           0 :         ucb::ContentInfo aInfo;
     632           0 :         if ( !( aCommand.Argument >>= aInfo ) )
     633             :         {
     634             :             OSL_FAIL( "Wrong argument type!" );
     635             :             ucbhelper::cancelCommandExecution(
     636             :                 uno::makeAny( lang::IllegalArgumentException(
     637             :                                     OUString( "Wrong argument type!" ),
     638             :                                     static_cast< cppu::OWeakObject * >( this ),
     639             :                                     -1 ) ),
     640           0 :                 Environment );
     641             :             // Unreachable
     642             :         }
     643             : 
     644           0 :         aRet <<= createNewContent( aInfo );
     645             :     }
     646             :     else
     647             :     {
     648             : 
     649             :         // Unsupported command
     650             : 
     651             : 
     652             :         ucbhelper::cancelCommandExecution(
     653             :             uno::makeAny( ucb::UnsupportedCommandException(
     654             :                                 OUString(),
     655             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
     656           0 :             Environment );
     657             :         // Unreachable
     658             :     }
     659             : 
     660           0 :     return aRet;
     661             : }
     662             : 
     663             : 
     664             : // virtual
     665           0 : void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ )
     666             :     throw( uno::RuntimeException, std::exception )
     667             : {
     668           0 : }
     669             : 
     670             : 
     671             : 
     672             : // XContentCreator methods.
     673             : 
     674             : 
     675             : 
     676             : // virtual
     677             : uno::Sequence< ucb::ContentInfo > SAL_CALL
     678           0 : Content::queryCreatableContentsInfo()
     679             :     throw( uno::RuntimeException, std::exception )
     680             : {
     681           0 :     return m_aProps.getCreatableContentsInfo();
     682             : }
     683             : 
     684             : 
     685             : // virtual
     686             : uno::Reference< ucb::XContent > SAL_CALL
     687           0 : Content::createNewContent( const ucb::ContentInfo& Info )
     688             :     throw( uno::RuntimeException, std::exception )
     689             : {
     690           0 :     if ( m_aProps.isContentCreator() )
     691             :     {
     692           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     693             : 
     694           0 :         if ( Info.Type.isEmpty() )
     695           0 :             return uno::Reference< ucb::XContent >();
     696             : 
     697           0 :         sal_Bool bCreateFolder = Info.Type == TDOC_FOLDER_CONTENT_TYPE;
     698             : 
     699             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
     700             :         // streams cannot be created as direct children of document root
     701           0 :         if ( !bCreateFolder && ( m_aProps.getType() == DOCUMENT ) )
     702             :         {
     703             :             OSL_FAIL( "Content::createNewContent - streams cannot be "
     704             :                         "created as direct children of document root!" );
     705           0 :             return uno::Reference< ucb::XContent >();
     706             :         }
     707             : #endif
     708           0 :         if ( !bCreateFolder && Info.Type != TDOC_STREAM_CONTENT_TYPE )
     709             :         {
     710             :             OSL_FAIL( "Content::createNewContent - unsupported type!" );
     711           0 :             return uno::Reference< ucb::XContent >();
     712             :         }
     713             : 
     714           0 :         OUString aURL = m_xIdentifier->getContentIdentifier();
     715             : 
     716             :         OSL_ENSURE( !aURL.isEmpty(),
     717             :                     "Content::createNewContent - empty identifier!" );
     718             : 
     719           0 :         if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
     720           0 :             aURL += "/";
     721             : 
     722           0 :         if ( bCreateFolder )
     723           0 :             aURL += "New_Folder";
     724             :         else
     725           0 :             aURL += "New_Stream";
     726             : 
     727             :         uno::Reference< ucb::XContentIdentifier > xId
     728           0 :             = new ::ucbhelper::ContentIdentifier( aURL );
     729             : 
     730           0 :         return create( m_xContext, m_pProvider, xId, Info );
     731             :     }
     732             :     else
     733             :     {
     734             :         OSL_FAIL( "createNewContent called on non-contentcreator object!" );
     735           0 :         return uno::Reference< ucb::XContent >();
     736             :     }
     737             : }
     738             : 
     739             : 
     740             : // virtual
     741           0 : OUString Content::getParentURL()
     742             : {
     743           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     744           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
     745           0 :     return aUri.getParentUri();
     746             : }
     747             : 
     748             : 
     749             : uno::Reference< ucb::XContentIdentifier >
     750           0 : Content::makeNewIdentifier( const OUString& rTitle )
     751             : {
     752           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     753             : 
     754             :     // Assemble new content identifier...
     755           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
     756           0 :     OUStringBuffer aNewURL = aUri.getParentUri();
     757           0 :     aNewURL.append( ::ucb_impl::urihelper::encodeSegment( rTitle ) );
     758             : 
     759             :     return
     760             :         uno::Reference< ucb::XContentIdentifier >(
     761           0 :             new ::ucbhelper::ContentIdentifier( aNewURL.makeStringAndClear() ) );
     762             : }
     763             : 
     764             : 
     765           0 : void Content::queryChildren( ContentRefList& rChildren )
     766             : {
     767           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     768             : 
     769             :     // Only folders (root, documents, folders) have children.
     770           0 :     if ( !m_aProps.getIsFolder() )
     771           0 :         return;
     772             : 
     773             :     // Obtain a list with a snapshot of all currently instanciated contents
     774             :     // from provider and extract the contents which are direct children
     775             :     // of this content.
     776             : 
     777           0 :     ::ucbhelper::ContentRefList aAllContents;
     778           0 :     m_xProvider->queryExistingContents( aAllContents );
     779             : 
     780           0 :     OUString aURL = m_xIdentifier->getContentIdentifier();
     781           0 :     sal_Int32 nURLPos = aURL.lastIndexOf( '/' );
     782             : 
     783           0 :     if ( nURLPos != ( aURL.getLength() - 1 ) )
     784             :     {
     785             :         // No trailing slash found. Append.
     786           0 :         aURL += "/";
     787             :     }
     788             : 
     789           0 :     sal_Int32 nLen = aURL.getLength();
     790             : 
     791           0 :     ::ucbhelper::ContentRefList::const_iterator it  = aAllContents.begin();
     792           0 :     ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
     793             : 
     794           0 :     while ( it != end )
     795             :     {
     796           0 :         ::ucbhelper::ContentImplHelperRef xChild = (*it);
     797             :         OUString aChildURL
     798           0 :             = xChild->getIdentifier()->getContentIdentifier();
     799             : 
     800             :         // Is aURL a prefix of aChildURL?
     801           0 :         if ( ( aChildURL.getLength() > nLen ) &&
     802           0 :              ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
     803             :         {
     804           0 :             sal_Int32 nPos = nLen;
     805           0 :             nPos = aChildURL.indexOf( '/', nPos );
     806             : 
     807           0 :             if ( ( nPos == -1 ) ||
     808           0 :                  ( nPos == ( aChildURL.getLength() - 1 ) ) )
     809             :             {
     810             :                 // No further slashes / only a final slash. It's a child!
     811             :                 rChildren.push_back(
     812             :                     ContentRef(
     813           0 :                         static_cast< Content * >( xChild.get() ) ) );
     814             :             }
     815             :         }
     816           0 :         ++it;
     817           0 :     }
     818             : }
     819             : 
     820             : 
     821           0 : sal_Bool Content::exchangeIdentity(
     822             :             const uno::Reference< ucb::XContentIdentifier >& xNewId )
     823             : {
     824           0 :     if ( !xNewId.is() )
     825           0 :         return sal_False;
     826             : 
     827           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
     828             : 
     829           0 :     uno::Reference< ucb::XContent > xThis = this;
     830             : 
     831             :     // Already persistent?
     832           0 :     if ( m_eState != PERSISTENT )
     833             :     {
     834             :         OSL_FAIL( "Content::exchangeIdentity - Not persistent!" );
     835           0 :         return sal_False;
     836             :     }
     837             : 
     838             :     // Only folders and streams can be renamed -> exchange identity.
     839           0 :     ContentType eType = m_aProps.getType();
     840           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
     841             :     {
     842             :         OSL_FAIL( "Content::exchangeIdentity - "
     843             :                                "Not supported by root or document!" );
     844           0 :         return sal_False;
     845             :     }
     846             : 
     847             :     // Exchange own identitity.
     848             : 
     849             :     // Fail, if a content with given id already exists.
     850           0 :     if ( !hasData( Uri( xNewId->getContentIdentifier() ) ) )
     851             :     {
     852           0 :         OUString aOldURL = m_xIdentifier->getContentIdentifier();
     853             : 
     854           0 :         aGuard.clear();
     855           0 :         if ( exchange( xNewId ) )
     856             :         {
     857           0 :             if ( eType == FOLDER )
     858             :             {
     859             :                 // Process instanciated children...
     860             : 
     861           0 :                 ContentRefList aChildren;
     862           0 :                 queryChildren( aChildren );
     863             : 
     864           0 :                 ContentRefList::const_iterator it  = aChildren.begin();
     865           0 :                 ContentRefList::const_iterator end = aChildren.end();
     866             : 
     867           0 :                 while ( it != end )
     868             :                 {
     869           0 :                     ContentRef xChild = (*it);
     870             : 
     871             :                     // Create new content identifier for the child...
     872             :                     uno::Reference< ucb::XContentIdentifier > xOldChildId
     873           0 :                                                     = xChild->getIdentifier();
     874             :                     OUString aOldChildURL
     875           0 :                         = xOldChildId->getContentIdentifier();
     876             :                     OUString aNewChildURL
     877             :                         = aOldChildURL.replaceAt(
     878             :                                         0,
     879             :                                         aOldURL.getLength(),
     880           0 :                                         xNewId->getContentIdentifier() );
     881             :                     uno::Reference< ucb::XContentIdentifier > xNewChildId
     882           0 :                         = new ::ucbhelper::ContentIdentifier( aNewChildURL );
     883             : 
     884           0 :                     if ( !xChild->exchangeIdentity( xNewChildId ) )
     885           0 :                         return sal_False;
     886             : 
     887           0 :                     ++it;
     888           0 :                 }
     889             :             }
     890           0 :             return sal_True;
     891           0 :         }
     892             :     }
     893             : 
     894             :     OSL_FAIL( "Content::exchangeIdentity - "
     895             :                 "Panic! Cannot exchange identity!" );
     896           0 :     return sal_False;
     897             : }
     898             : 
     899             : 
     900             : // static
     901           0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
     902             :                 const uno::Reference< uno::XComponentContext >& rxContext,
     903             :                 const uno::Sequence< beans::Property >& rProperties,
     904             :                 ContentProvider* pProvider,
     905             :                 const OUString& rContentId )
     906             : {
     907           0 :     ContentProperties aData;
     908           0 :     if ( loadData( pProvider, rContentId, aData ) )
     909             :     {
     910             :         return getPropertyValues(
     911           0 :             rxContext, rProperties, aData, pProvider, rContentId );
     912             :     }
     913             :     else
     914             :     {
     915             :         rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
     916           0 :             = new ::ucbhelper::PropertyValueSet( rxContext );
     917             : 
     918           0 :         sal_Int32 nCount = rProperties.getLength();
     919           0 :         if ( nCount )
     920             :         {
     921           0 :             const beans::Property* pProps = rProperties.getConstArray();
     922           0 :             for ( sal_Int32 n = 0; n < nCount; ++n )
     923           0 :                 xRow->appendVoid( pProps[ n ] );
     924             :         }
     925             : 
     926           0 :         return uno::Reference< sdbc::XRow >( xRow.get() );
     927           0 :     }
     928             : }
     929             : 
     930             : 
     931             : // static
     932           0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
     933             :                 const uno::Reference< uno::XComponentContext >& rxContext,
     934             :                 const uno::Sequence< beans::Property >& rProperties,
     935             :                 const ContentProperties& rData,
     936             :                 ContentProvider* pProvider,
     937             :                 const OUString& rContentId )
     938             : {
     939             :     // Note: Empty sequence means "get values of all supported properties".
     940             : 
     941             :     rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
     942           0 :         = new ::ucbhelper::PropertyValueSet( rxContext );
     943             : 
     944           0 :     sal_Int32 nCount = rProperties.getLength();
     945           0 :     if ( nCount )
     946             :     {
     947           0 :         uno::Reference< beans::XPropertySet > xAdditionalPropSet;
     948           0 :         sal_Bool bTriedToGetAdditionalPropSet = sal_False;
     949             : 
     950           0 :         const beans::Property* pProps = rProperties.getConstArray();
     951           0 :         for ( sal_Int32 n = 0; n < nCount; ++n )
     952             :         {
     953           0 :             const beans::Property& rProp = pProps[ n ];
     954             : 
     955             :             // Process Core properties.
     956             : 
     957           0 :             if ( rProp.Name == "ContentType" )
     958             :             {
     959           0 :                 xRow->appendString ( rProp, rData.getContentType() );
     960             :             }
     961           0 :             else if ( rProp.Name == "Title" )
     962             :             {
     963           0 :                 xRow->appendString ( rProp, rData.getTitle() );
     964             :             }
     965           0 :             else if ( rProp.Name == "IsDocument" )
     966             :             {
     967           0 :                 xRow->appendBoolean( rProp, rData.getIsDocument() );
     968             :             }
     969           0 :             else if ( rProp.Name == "IsFolder" )
     970             :             {
     971           0 :                 xRow->appendBoolean( rProp, rData.getIsFolder() );
     972             :             }
     973           0 :             else if ( rProp.Name == "CreatableContentsInfo" )
     974             :             {
     975             :                 xRow->appendObject(
     976           0 :                     rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
     977             :             }
     978           0 :             else if ( rProp.Name == "Storage" )
     979             :             {
     980             :                 // Storage is only supported by folders.
     981           0 :                 ContentType eType = rData.getType();
     982           0 :                 if ( eType == FOLDER )
     983             :                     xRow->appendObject(
     984             :                         rProp,
     985             :                         uno::makeAny(
     986           0 :                             pProvider->queryStorageClone( rContentId ) ) );
     987             :                 else
     988           0 :                     xRow->appendVoid( rProp );
     989             :             }
     990           0 :             else if ( rProp.Name == "DocumentModel" )
     991             :             {
     992             :                 // DocumentModel is only supported by documents.
     993           0 :                 ContentType eType = rData.getType();
     994           0 :                 if ( eType == DOCUMENT )
     995             :                     xRow->appendObject(
     996             :                         rProp,
     997             :                         uno::makeAny(
     998           0 :                             pProvider->queryDocumentModel( rContentId ) ) );
     999             :                 else
    1000           0 :                     xRow->appendVoid( rProp );
    1001             :             }
    1002             :             else
    1003             :             {
    1004             :                 // Not a Core Property! Maybe it's an Additional Core Property?!
    1005             : 
    1006           0 :                 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
    1007             :                 {
    1008             :                     xAdditionalPropSet
    1009           0 :                         = uno::Reference< beans::XPropertySet >(
    1010             :                             pProvider->getAdditionalPropertySet( rContentId,
    1011             :                                                                  false ),
    1012           0 :                             uno::UNO_QUERY );
    1013           0 :                     bTriedToGetAdditionalPropSet = sal_True;
    1014             :                 }
    1015             : 
    1016           0 :                 if ( xAdditionalPropSet.is() )
    1017             :                 {
    1018           0 :                     if ( !xRow->appendPropertySetValue(
    1019             :                                                 xAdditionalPropSet,
    1020           0 :                                                 rProp ) )
    1021             :                     {
    1022             :                         // Append empty entry.
    1023           0 :                         xRow->appendVoid( rProp );
    1024             :                     }
    1025             :                 }
    1026             :                 else
    1027             :                 {
    1028             :                     // Append empty entry.
    1029           0 :                     xRow->appendVoid( rProp );
    1030             :                 }
    1031             :             }
    1032           0 :         }
    1033             :     }
    1034             :     else
    1035             :     {
    1036             :         // Append all Core Properties.
    1037             :         xRow->appendString (
    1038             :             beans::Property( OUString("ContentType"),
    1039             :                       -1,
    1040           0 :                       getCppuType( static_cast< const OUString * >( 0 ) ),
    1041             :                       beans::PropertyAttribute::BOUND
    1042             :                         | beans::PropertyAttribute::READONLY ),
    1043           0 :             rData.getContentType() );
    1044             : 
    1045           0 :         ContentType eType = rData.getType();
    1046             : 
    1047             :         xRow->appendString (
    1048             :             beans::Property( OUString("Title"),
    1049             :                       -1,
    1050           0 :                       getCppuType( static_cast< const OUString * >( 0 ) ),
    1051             :                       // Title is read-only for root and documents.
    1052             :                       beans::PropertyAttribute::BOUND |
    1053           0 :                       ( ( eType == ROOT ) || ( eType == DOCUMENT )
    1054             :                         ? beans::PropertyAttribute::READONLY
    1055             :                         : 0 ) ),
    1056           0 :             rData.getTitle() );
    1057             :         xRow->appendBoolean(
    1058             :             beans::Property( OUString("IsDocument"),
    1059             :                       -1,
    1060           0 :                       getCppuBooleanType(),
    1061             :                       beans::PropertyAttribute::BOUND
    1062             :                         | beans::PropertyAttribute::READONLY ),
    1063           0 :             rData.getIsDocument() );
    1064             :         xRow->appendBoolean(
    1065             :             beans::Property( OUString("IsFolder"),
    1066             :                       -1,
    1067           0 :                       getCppuBooleanType(),
    1068             :                       beans::PropertyAttribute::BOUND
    1069             :                         | beans::PropertyAttribute::READONLY ),
    1070           0 :             rData.getIsFolder() );
    1071             :         xRow->appendObject(
    1072             :             beans::Property(
    1073             :                 OUString("CreatableContentsInfo"),
    1074             :                 -1,
    1075             :                 getCppuType( static_cast<
    1076           0 :                         const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
    1077             :                 beans::PropertyAttribute::BOUND
    1078             :                 | beans::PropertyAttribute::READONLY ),
    1079           0 :             uno::makeAny( rData.getCreatableContentsInfo() ) );
    1080             : 
    1081             :         // Storage is only supported by folders.
    1082           0 :         if ( eType == FOLDER )
    1083             :             xRow->appendObject(
    1084             :                 beans::Property( OUString("Storage"),
    1085             :                           -1,
    1086             :                           getCppuType(
    1087             :                             static_cast<
    1088           0 :                                 const uno::Reference< embed::XStorage > * >( 0 ) ),
    1089             :                           beans::PropertyAttribute::BOUND
    1090             :                             | beans::PropertyAttribute::READONLY ),
    1091           0 :                 uno::makeAny( pProvider->queryStorageClone( rContentId ) ) );
    1092             : 
    1093             :         // DocumentModel is only supported by documents.
    1094           0 :         if ( eType == DOCUMENT )
    1095             :             xRow->appendObject(
    1096             :                 beans::Property( OUString("DocumentModel"),
    1097             :                           -1,
    1098             :                           getCppuType(
    1099             :                             static_cast<
    1100           0 :                                 const uno::Reference< frame::XModel > * >( 0 ) ),
    1101             :                           beans::PropertyAttribute::BOUND
    1102             :                             | beans::PropertyAttribute::READONLY ),
    1103             :                 uno::makeAny(
    1104           0 :                     pProvider->queryDocumentModel( rContentId ) ) );
    1105             : 
    1106             :         // Append all Additional Core Properties.
    1107             : 
    1108             :         uno::Reference< beans::XPropertySet > xSet(
    1109             :             pProvider->getAdditionalPropertySet( rContentId, false ),
    1110           0 :             uno::UNO_QUERY );
    1111           0 :         xRow->appendPropertySet( xSet );
    1112             :     }
    1113             : 
    1114           0 :     return uno::Reference< sdbc::XRow >( xRow.get() );
    1115             : }
    1116             : 
    1117             : 
    1118           0 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
    1119             :                         const uno::Sequence< beans::Property >& rProperties )
    1120             : {
    1121           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1122             :     return getPropertyValues( m_xContext,
    1123             :                               rProperties,
    1124             :                               m_aProps,
    1125             :                               m_pProvider,
    1126           0 :                               m_xIdentifier->getContentIdentifier() );
    1127             : }
    1128             : 
    1129             : 
    1130           0 : uno::Sequence< uno::Any > Content::setPropertyValues(
    1131             :         const uno::Sequence< beans::PropertyValue >& rValues,
    1132             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1133             :     throw( uno::Exception )
    1134             : {
    1135           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1136             : 
    1137           0 :     uno::Sequence< uno::Any > aRet( rValues.getLength() );
    1138           0 :     uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
    1139           0 :     sal_Int32 nChanged = 0;
    1140             : 
    1141           0 :     beans::PropertyChangeEvent aEvent;
    1142           0 :     aEvent.Source         = static_cast< cppu::OWeakObject * >( this );
    1143           0 :     aEvent.Further        = sal_False;
    1144             :     //    aEvent.PropertyName   =
    1145           0 :     aEvent.PropertyHandle = -1;
    1146             :     //    aEvent.OldValue       =
    1147             :     //    aEvent.NewValue       =
    1148             : 
    1149           0 :     const beans::PropertyValue* pValues = rValues.getConstArray();
    1150           0 :     sal_Int32 nCount = rValues.getLength();
    1151             : 
    1152           0 :     uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
    1153           0 :     sal_Bool bTriedToGetAdditionalPropSet = sal_False;
    1154             : 
    1155           0 :     sal_Bool bExchange = sal_False;
    1156           0 :     OUString aOldTitle;
    1157           0 :     sal_Int32 nTitlePos = -1;
    1158             : 
    1159           0 :     for ( sal_Int32 n = 0; n < nCount; ++n )
    1160             :     {
    1161           0 :         const beans::PropertyValue& rValue = pValues[ n ];
    1162             : 
    1163           0 :         if ( rValue.Name == "ContentType" )
    1164             :         {
    1165             :             // Read-only property!
    1166           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1167             :                             OUString( "Property is read-only!" ),
    1168           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1169             :         }
    1170           0 :         else if ( rValue.Name == "IsDocument" )
    1171             :         {
    1172             :             // Read-only property!
    1173           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1174             :                             OUString( "Property is read-only!" ),
    1175           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1176             :         }
    1177           0 :         else if ( rValue.Name == "IsFolder" )
    1178             :         {
    1179             :             // Read-only property!
    1180           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1181             :                             OUString( "Property is read-only!" ),
    1182           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1183             :         }
    1184           0 :         else if ( rValue.Name == "CreatableContentsInfo" )
    1185             :         {
    1186             :             // Read-only property!
    1187           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1188             :                             OUString( "Property is read-only!" ),
    1189           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1190             :         }
    1191           0 :         else if ( rValue.Name == "Title" )
    1192             :         {
    1193             :             // Title is read-only for root and documents.
    1194           0 :             ContentType eType = m_aProps.getType();
    1195           0 :             if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    1196             :             {
    1197           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1198             :                                 OUString( "Property is read-only!" ),
    1199           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1200             :             }
    1201             :             else
    1202             :             {
    1203           0 :                 OUString aNewValue;
    1204           0 :                 if ( rValue.Value >>= aNewValue )
    1205             :                 {
    1206             :                     // No empty titles!
    1207           0 :                     if ( !aNewValue.isEmpty() )
    1208             :                     {
    1209           0 :                         if ( aNewValue != m_aProps.getTitle() )
    1210             :                         {
    1211             :                             // modified title -> modified URL -> exchange !
    1212           0 :                             if ( m_eState == PERSISTENT )
    1213           0 :                                 bExchange = sal_True;
    1214             : 
    1215           0 :                             aOldTitle = m_aProps.getTitle();
    1216           0 :                             m_aProps.setTitle( aNewValue );
    1217             : 
    1218             :                             // property change event will be sent later...
    1219             : 
    1220             :                             // remember position within sequence of values
    1221             :                             // (for error handling).
    1222           0 :                             nTitlePos = n;
    1223             :                         }
    1224             :                     }
    1225             :                     else
    1226             :                     {
    1227           0 :                         aRet[ n ] <<= lang::IllegalArgumentException(
    1228             :                                     OUString( "Empty Title not allowed!" ),
    1229             :                                     static_cast< cppu::OWeakObject * >( this ),
    1230           0 :                                     -1 );
    1231             :                     }
    1232             :                 }
    1233             :                 else
    1234             :                 {
    1235           0 :                     aRet[ n ] <<= beans::IllegalTypeException(
    1236             :                                 OUString( "Title Property value has wrong type!" ),
    1237           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1238           0 :                 }
    1239             :             }
    1240             :         }
    1241           0 :         else if ( rValue.Name == "Storage" )
    1242             :         {
    1243           0 :             ContentType eType = m_aProps.getType();
    1244           0 :             if ( eType == FOLDER )
    1245             :             {
    1246           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1247             :                                 OUString( "Property is read-only!" ),
    1248           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1249             :             }
    1250             :             else
    1251             :             {
    1252             :                 // Storage is only supported by folders.
    1253           0 :                 aRet[ n ] <<= beans::UnknownPropertyException(
    1254             :                             OUString( "Storage property only supported by folders" ),
    1255           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1256             :             }
    1257             :         }
    1258           0 :         else if ( rValue.Name == "DocumentModel" )
    1259             :         {
    1260           0 :             ContentType eType = m_aProps.getType();
    1261           0 :             if ( eType == DOCUMENT )
    1262             :             {
    1263           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1264             :                                 OUString( "Property is read-only!" ),
    1265           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1266             :             }
    1267             :             else
    1268             :             {
    1269             :                 // Storage is only supported by folders.
    1270           0 :                 aRet[ n ] <<= beans::UnknownPropertyException(
    1271             :                             OUString( "DocumentModel property only supported by "
    1272             :                                 "documents" ),
    1273           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1274             :             }
    1275             :         }
    1276             :         else
    1277             :         {
    1278             :             // Not a Core Property! Maybe it's an Additional Core Property?!
    1279             : 
    1280           0 :             if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
    1281             :             {
    1282           0 :                 xAdditionalPropSet = getAdditionalPropertySet( false );
    1283           0 :                 bTriedToGetAdditionalPropSet = sal_True;
    1284             :             }
    1285             : 
    1286           0 :             if ( xAdditionalPropSet.is() )
    1287             :             {
    1288             :                 try
    1289             :                 {
    1290           0 :                     uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
    1291           0 :                                                                 rValue.Name );
    1292           0 :                     if ( aOldValue != rValue.Value )
    1293             :                     {
    1294           0 :                         xAdditionalPropSet->setPropertyValue(
    1295           0 :                                                 rValue.Name, rValue.Value );
    1296             : 
    1297           0 :                         aEvent.PropertyName = rValue.Name;
    1298           0 :                         aEvent.OldValue     = aOldValue;
    1299           0 :                         aEvent.NewValue     = rValue.Value;
    1300             : 
    1301           0 :                         aChanges.getArray()[ nChanged ] = aEvent;
    1302           0 :                         nChanged++;
    1303           0 :                     }
    1304             :                 }
    1305           0 :                 catch ( beans::UnknownPropertyException const & e )
    1306             :                 {
    1307           0 :                     aRet[ n ] <<= e;
    1308             :                 }
    1309           0 :                 catch ( lang::WrappedTargetException const & e )
    1310             :                 {
    1311           0 :                     aRet[ n ] <<= e;
    1312             :                 }
    1313           0 :                 catch ( beans::PropertyVetoException const & e )
    1314             :                 {
    1315           0 :                     aRet[ n ] <<= e;
    1316             :                 }
    1317           0 :                 catch ( lang::IllegalArgumentException const & e )
    1318             :                 {
    1319           0 :                     aRet[ n ] <<= e;
    1320             :                 }
    1321             :             }
    1322             :             else
    1323             :             {
    1324           0 :                 aRet[ n ] <<= uno::Exception(
    1325             :                                 OUString( "No property set for storing the value!" ),
    1326           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1327             :             }
    1328             :         }
    1329             :     }
    1330             : 
    1331           0 :     if ( bExchange )
    1332             :     {
    1333             :         uno::Reference< ucb::XContentIdentifier > xOldId
    1334           0 :             = m_xIdentifier;
    1335             :         uno::Reference< ucb::XContentIdentifier > xNewId
    1336           0 :             = makeNewIdentifier( m_aProps.getTitle() );
    1337             : 
    1338           0 :         aGuard.clear();
    1339           0 :         if ( exchangeIdentity( xNewId ) )
    1340             :         {
    1341             :             // Adapt persistent data.
    1342           0 :             renameData( xOldId, xNewId );
    1343             : 
    1344             :             // Adapt Additional Core Properties.
    1345           0 :             renameAdditionalPropertySet( xOldId->getContentIdentifier(),
    1346           0 :                                          xNewId->getContentIdentifier(),
    1347           0 :                                          true );
    1348             :         }
    1349             :         else
    1350             :         {
    1351             :             // Roll-back.
    1352           0 :             m_aProps.setTitle( aOldTitle );
    1353           0 :             aOldTitle = "";
    1354             : 
    1355             :             // Set error .
    1356           0 :             aRet[ nTitlePos ] <<= uno::Exception(
    1357             :                     OUString("Exchange failed!"),
    1358           0 :                     static_cast< cppu::OWeakObject * >( this ) );
    1359           0 :         }
    1360             :     }
    1361             : 
    1362           0 :     if ( !aOldTitle.isEmpty() )
    1363             :     {
    1364           0 :         aEvent.PropertyName = "Title";
    1365           0 :         aEvent.OldValue     = uno::makeAny( aOldTitle );
    1366           0 :         aEvent.NewValue     = uno::makeAny( m_aProps.getTitle() );
    1367             : 
    1368           0 :         aChanges.getArray()[ nChanged ] = aEvent;
    1369           0 :         nChanged++;
    1370             :     }
    1371             : 
    1372           0 :     if ( nChanged > 0 )
    1373             :     {
    1374             :         // Save changes, if content was already made persistent.
    1375           0 :         if ( !bExchange && ( m_eState == PERSISTENT ) )
    1376             :         {
    1377           0 :             if ( !storeData( uno::Reference< io::XInputStream >(), xEnv ) )
    1378             :             {
    1379             :                 uno::Any aProps
    1380             :                     = uno::makeAny(
    1381             :                              beans::PropertyValue(
    1382             :                                  OUString( "Uri"),
    1383             :                                  -1,
    1384           0 :                                  uno::makeAny(m_xIdentifier->
    1385           0 :                                                   getContentIdentifier()),
    1386           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1387             :                 ucbhelper::cancelCommandExecution(
    1388             :                     ucb::IOErrorCode_CANT_WRITE,
    1389             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1390             :                     xEnv,
    1391             :                     OUString( "Cannot store persistent data!" ),
    1392           0 :                     this );
    1393             :                 // Unreachable
    1394             :             }
    1395             :         }
    1396             : 
    1397           0 :         aChanges.realloc( nChanged );
    1398             : 
    1399           0 :         aGuard.clear();
    1400           0 :         notifyPropertiesChange( aChanges );
    1401             :     }
    1402             : 
    1403           0 :     return aRet;
    1404             : }
    1405             : 
    1406             : 
    1407           0 : uno::Any Content::open(
    1408             :                 const ucb::OpenCommandArgument2& rArg,
    1409             :                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1410             :     throw( uno::Exception )
    1411             : {
    1412           0 :     if ( rArg.Mode == ucb::OpenMode::ALL ||
    1413           0 :          rArg.Mode == ucb::OpenMode::FOLDERS ||
    1414           0 :          rArg.Mode == ucb::OpenMode::DOCUMENTS )
    1415             :     {
    1416             : 
    1417             :         // open command for a folder content
    1418             : 
    1419             : 
    1420             :         uno::Reference< ucb::XDynamicResultSet > xSet
    1421           0 :             = new DynamicResultSet( m_xContext, this, rArg );
    1422           0 :         return uno::makeAny( xSet );
    1423             :     }
    1424             :     else
    1425             :     {
    1426             : 
    1427             :         // open command for a document content
    1428             : 
    1429             : 
    1430           0 :         if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
    1431           0 :              ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
    1432             :         {
    1433             :             // Currently(?) unsupported.
    1434             :             ucbhelper::cancelCommandExecution(
    1435             :                 uno::makeAny( ucb::UnsupportedOpenModeException(
    1436             :                                     OUString(),
    1437             :                                     static_cast< cppu::OWeakObject * >( this ),
    1438             :                                     sal_Int16( rArg.Mode ) ) ),
    1439           0 :                 xEnv );
    1440             :             // Unreachable
    1441             :         }
    1442             : 
    1443           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1444             : 
    1445             :         uno::Reference< io::XActiveDataStreamer > xDataStreamer(
    1446           0 :                                         rArg.Sink, uno::UNO_QUERY );
    1447           0 :         if ( xDataStreamer.is() )
    1448             :         {
    1449             :             // May throw CommandFailedException, DocumentPasswordRequest!
    1450           0 :             uno::Reference< io::XStream > xStream = getStream( xEnv );
    1451           0 :             if ( !xStream.is() )
    1452             :             {
    1453             :                 // No interaction if we are not persistent!
    1454             :                 uno::Any aProps
    1455             :                     = uno::makeAny(
    1456             :                              beans::PropertyValue(
    1457             :                                  OUString( "Uri"),
    1458             :                                  -1,
    1459           0 :                                  uno::makeAny(m_xIdentifier->
    1460           0 :                                                   getContentIdentifier()),
    1461           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1462             :                 ucbhelper::cancelCommandExecution(
    1463             :                     ucb::IOErrorCode_CANT_READ,
    1464             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1465           0 :                     m_eState == PERSISTENT
    1466             :                         ? xEnv
    1467             :                         : uno::Reference< ucb::XCommandEnvironment >(),
    1468             :                     OUString( "Got no data stream!" ),
    1469           0 :                     this );
    1470             :                 // Unreachable
    1471             :             }
    1472             : 
    1473             :             // Done.
    1474           0 :             xDataStreamer->setStream( xStream );
    1475             :         }
    1476             :         else
    1477             :         {
    1478           0 :             uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
    1479           0 :             if ( xOut.is() )
    1480             :             {
    1481             :                 // PUSH: write data into xOut
    1482             : 
    1483             :                 // May throw CommandFailedException, DocumentPasswordRequest!
    1484           0 :                 uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
    1485           0 :                 if ( !xIn.is() )
    1486             :                 {
    1487             :                     // No interaction if we are not persistent!
    1488             :                     uno::Any aProps
    1489             :                         = uno::makeAny(
    1490             :                                  beans::PropertyValue(
    1491             :                                      OUString( "Uri"),
    1492             :                                      -1,
    1493           0 :                                      uno::makeAny(m_xIdentifier->
    1494           0 :                                                       getContentIdentifier()),
    1495           0 :                                      beans::PropertyState_DIRECT_VALUE));
    1496             :                     ucbhelper::cancelCommandExecution(
    1497             :                         ucb::IOErrorCode_CANT_READ,
    1498             :                         uno::Sequence< uno::Any >(&aProps, 1),
    1499           0 :                         m_eState == PERSISTENT
    1500             :                             ? xEnv
    1501             :                             : uno::Reference< ucb::XCommandEnvironment >(),
    1502             :                         OUString("Got no data stream!"),
    1503           0 :                         this );
    1504             :                     // Unreachable
    1505             :                 }
    1506             : 
    1507             :                 try
    1508             :                 {
    1509           0 :                     uno::Sequence< sal_Int8 > aBuffer;
    1510           0 :                     sal_Int32  nRead = xIn->readSomeBytes( aBuffer, 65536 );
    1511             : 
    1512           0 :                     while ( nRead > 0 )
    1513             :                     {
    1514           0 :                         aBuffer.realloc( nRead );
    1515           0 :                         xOut->writeBytes( aBuffer );
    1516           0 :                         aBuffer.realloc( 0 );
    1517           0 :                         nRead = xIn->readSomeBytes( aBuffer, 65536 );
    1518             :                     }
    1519             : 
    1520           0 :                     xOut->closeOutput();
    1521             :                 }
    1522           0 :                 catch ( io::NotConnectedException const & )
    1523             :                 {
    1524             :                     // closeOutput, readSomeBytes, writeBytes
    1525             :                 }
    1526           0 :                 catch ( io::BufferSizeExceededException const & )
    1527             :                 {
    1528             :                     // closeOutput, readSomeBytes, writeBytes
    1529             :                 }
    1530           0 :                 catch ( io::IOException const & )
    1531             :                 {
    1532             :                     // closeOutput, readSomeBytes, writeBytes
    1533           0 :                 }
    1534             :             }
    1535             :             else
    1536             :             {
    1537             :                 uno::Reference< io::XActiveDataSink > xDataSink(
    1538           0 :                                                 rArg.Sink, uno::UNO_QUERY );
    1539           0 :                 if ( xDataSink.is() )
    1540             :                 {
    1541             :                     // PULL: wait for client read
    1542             : 
    1543             :                     // May throw CommandFailedException, DocumentPasswordRequest!
    1544           0 :                     uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
    1545           0 :                     if ( !xIn.is() )
    1546             :                     {
    1547             :                         // No interaction if we are not persistent!
    1548             :                         uno::Any aProps
    1549             :                             = uno::makeAny(
    1550             :                                      beans::PropertyValue(
    1551             :                                          OUString( "Uri"),
    1552             :                                          -1,
    1553           0 :                                          uno::makeAny(m_xIdentifier->
    1554           0 :                                                           getContentIdentifier()),
    1555           0 :                                          beans::PropertyState_DIRECT_VALUE));
    1556             :                         ucbhelper::cancelCommandExecution(
    1557             :                             ucb::IOErrorCode_CANT_READ,
    1558             :                             uno::Sequence< uno::Any >(&aProps, 1),
    1559           0 :                             m_eState == PERSISTENT
    1560             :                                 ? xEnv
    1561             :                                 : uno::Reference<
    1562             :                                       ucb::XCommandEnvironment >(),
    1563             :                             OUString( "Got no data stream!" ),
    1564           0 :                             this );
    1565             :                         // Unreachable
    1566             :                     }
    1567             : 
    1568             :                     // Done.
    1569           0 :                     xDataSink->setInputStream( xIn );
    1570             :                 }
    1571             :                 else
    1572             :                 {
    1573             :                     ucbhelper::cancelCommandExecution(
    1574             :                         uno::makeAny(
    1575             :                             ucb::UnsupportedDataSinkException(
    1576             :                                     OUString(),
    1577             :                                     static_cast< cppu::OWeakObject * >( this ),
    1578             :                                     rArg.Sink ) ),
    1579           0 :                         xEnv );
    1580             :                     // Unreachable
    1581           0 :                 }
    1582           0 :             }
    1583           0 :         }
    1584             :     }
    1585             : 
    1586           0 :     return uno::Any();
    1587             : }
    1588             : 
    1589             : 
    1590           0 : void Content::insert( const uno::Reference< io::XInputStream >& xData,
    1591             :                       sal_Int32 nNameClashResolve,
    1592             :                       const uno::Reference<
    1593             :                           ucb::XCommandEnvironment > & xEnv )
    1594             :     throw( uno::Exception )
    1595             : {
    1596           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1597             : 
    1598           0 :     ContentType eType = m_aProps.getType();
    1599             : 
    1600             :     OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
    1601             :                 "insert command only supported by streams and folders!" );
    1602             : 
    1603           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    1604             : 
    1605             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    1606             : #if OSL_DEBUG_LEVEL > 0
    1607             :     if ( eType == STREAM )
    1608             :     {
    1609             :         Uri aParentUri( aUri.getParentUri() );
    1610             :         OSL_ENSURE( !aParentUri.isDocument(),
    1611             :                     "insert command not supported by streams that are direct "
    1612             :                     "children of document root!" );
    1613             :     }
    1614             : #endif
    1615             : #endif
    1616             : 
    1617             :     // Check, if all required properties were set.
    1618           0 :     if ( eType == FOLDER )
    1619             :     {
    1620             :         // Required: Title
    1621             : 
    1622           0 :         if ( m_aProps.getTitle().isEmpty() )
    1623           0 :             m_aProps.setTitle( aUri.getDecodedName() );
    1624             :     }
    1625             :     else // stream
    1626             :     {
    1627             :         // Required: data
    1628             : 
    1629           0 :         if ( !xData.is() )
    1630             :         {
    1631             :             ucbhelper::cancelCommandExecution(
    1632             :                 uno::makeAny( ucb::MissingInputStreamException(
    1633             :                                 OUString(),
    1634             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1635           0 :                 xEnv );
    1636             :             // Unreachable
    1637             :         }
    1638             : 
    1639             :         // Required: Title
    1640             : 
    1641           0 :         if ( m_aProps.getTitle().isEmpty() )
    1642           0 :             m_aProps.setTitle( aUri.getDecodedName() );
    1643             :     }
    1644             : 
    1645           0 :     OUStringBuffer aNewURL = aUri.getParentUri();
    1646           0 :     aNewURL.append( m_aProps.getTitle() );
    1647           0 :     Uri aNewUri( aNewURL.makeStringAndClear() );
    1648             : 
    1649             :     // Handle possible name clash...
    1650           0 :     switch ( nNameClashResolve )
    1651             :     {
    1652             :         // fail.
    1653             :         case ucb::NameClash::ERROR:
    1654           0 :             if ( hasData( aNewUri ) )
    1655             :             {
    1656             :                 ucbhelper::cancelCommandExecution(
    1657             :                     uno::makeAny( ucb::NameClashException(
    1658             :                                     OUString(),
    1659             :                                     static_cast< cppu::OWeakObject * >( this ),
    1660             :                                     task::InteractionClassification_ERROR,
    1661           0 :                                     m_aProps.getTitle() ) ),
    1662           0 :                     xEnv );
    1663             :                 // Unreachable
    1664             :             }
    1665           0 :             break;
    1666             : 
    1667             :         // replace (possibly) existing object.
    1668             :         case ucb::NameClash::OVERWRITE:
    1669           0 :             break;
    1670             : 
    1671             :         // "invent" a new valid title.
    1672             :         case ucb::NameClash::RENAME:
    1673           0 :             if ( hasData( aNewUri ) )
    1674             :             {
    1675           0 :                 sal_Int32 nTry = 0;
    1676             : 
    1677           0 :                 do
    1678             :                 {
    1679           0 :                     OUStringBuffer aNew = aNewUri.getUri();
    1680           0 :                     aNew.appendAscii( "_" );
    1681           0 :                     aNew.append( OUString::number( ++nTry ) );
    1682           0 :                     aNewUri.setUri( aNew.makeStringAndClear() );
    1683             :                 }
    1684           0 :                 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
    1685             : 
    1686           0 :                 if ( nTry == 1000 )
    1687             :                 {
    1688             :                     ucbhelper::cancelCommandExecution(
    1689             :                         uno::makeAny(
    1690             :                             ucb::UnsupportedNameClashException(
    1691             :                                 OUString( "Unable to resolve name clash!" ),
    1692             :                                 static_cast< cppu::OWeakObject * >( this ),
    1693             :                                 nNameClashResolve ) ),
    1694           0 :                         xEnv );
    1695             :                     // Unreachable
    1696             :                 }
    1697             :                 else
    1698             :                 {
    1699           0 :                     OUStringBuffer aNewTitle = m_aProps.getTitle();
    1700           0 :                     aNewTitle.appendAscii( "_" );
    1701           0 :                     aNewTitle.append( OUString::number( ++nTry ) );
    1702           0 :                     m_aProps.setTitle( aNewTitle.makeStringAndClear() );
    1703             :                 }
    1704             :             }
    1705           0 :             break;
    1706             : 
    1707             :         case ucb::NameClash::KEEP: // deprecated
    1708             :         case ucb::NameClash::ASK:
    1709             :         default:
    1710           0 :             if ( hasData( aNewUri ) )
    1711             :             {
    1712             :                 ucbhelper::cancelCommandExecution(
    1713             :                     uno::makeAny(
    1714             :                         ucb::UnsupportedNameClashException(
    1715             :                             OUString(),
    1716             :                             static_cast< cppu::OWeakObject * >( this ),
    1717             :                             nNameClashResolve ) ),
    1718           0 :                     xEnv );
    1719             :                 // Unreachable
    1720             :             }
    1721           0 :             break;
    1722             :     }
    1723             : 
    1724             :     // Identifier changed?
    1725           0 :     sal_Bool bNewId = ( aUri != aNewUri );
    1726             : 
    1727           0 :     if ( bNewId )
    1728             :     {
    1729             :         m_xIdentifier
    1730           0 :             = new ::ucbhelper::ContentIdentifier( aNewUri.getUri() );
    1731             :     }
    1732             : 
    1733           0 :     if ( !storeData( xData, xEnv ) )
    1734             :     {
    1735             :         uno::Any aProps
    1736             :             = uno::makeAny(beans::PropertyValue(
    1737             :                                   OUString( "Uri"),
    1738             :                                   -1,
    1739           0 :                                   uno::makeAny(m_xIdentifier->
    1740           0 :                                                    getContentIdentifier()),
    1741           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1742             :         ucbhelper::cancelCommandExecution(
    1743             :             ucb::IOErrorCode_CANT_WRITE,
    1744             :             uno::Sequence< uno::Any >(&aProps, 1),
    1745             :             xEnv,
    1746             :             OUString("Cannot store persistent data!"),
    1747           0 :             this );
    1748             :         // Unreachable
    1749             :     }
    1750             : 
    1751           0 :     m_eState = PERSISTENT;
    1752             : 
    1753           0 :     if ( bNewId )
    1754             :     {
    1755             :         //loadData( m_pProvider, m_aUri, m_aProps );
    1756             : 
    1757           0 :         aGuard.clear();
    1758           0 :         inserted();
    1759           0 :     }
    1760           0 : }
    1761             : 
    1762             : 
    1763           0 : void Content::destroy( sal_Bool bDeletePhysical,
    1764             :                        const uno::Reference<
    1765             :                            ucb::XCommandEnvironment > & xEnv )
    1766             :     throw( uno::Exception )
    1767             : {
    1768             :     // @@@ take care about bDeletePhysical -> trashcan support
    1769             : 
    1770           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1771             : 
    1772           0 :     ContentType eType = m_aProps.getType();
    1773             : 
    1774             :     OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
    1775             :                 "delete command only supported by streams and folders!" );
    1776             : 
    1777           0 :     uno::Reference< ucb::XContent > xThis = this;
    1778             : 
    1779             :     // Persistent?
    1780           0 :     if ( m_eState != PERSISTENT )
    1781             :     {
    1782             :         ucbhelper::cancelCommandExecution(
    1783             :             uno::makeAny( ucb::UnsupportedCommandException(
    1784             :                                 OUString( "Not persistent!" ),
    1785             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1786           0 :             xEnv );
    1787             :         // Unreachable
    1788             :     }
    1789             : 
    1790           0 :     m_eState = DEAD;
    1791             : 
    1792           0 :     aGuard.clear();
    1793           0 :     deleted();
    1794             : 
    1795           0 :     if ( eType == FOLDER )
    1796             :     {
    1797             :         // Process instanciated children...
    1798             : 
    1799           0 :         ContentRefList aChildren;
    1800           0 :         queryChildren( aChildren );
    1801             : 
    1802           0 :         ContentRefList::const_iterator it  = aChildren.begin();
    1803           0 :         ContentRefList::const_iterator end = aChildren.end();
    1804             : 
    1805           0 :         while ( it != end )
    1806             :         {
    1807           0 :             (*it)->destroy( bDeletePhysical, xEnv );
    1808           0 :             ++it;
    1809           0 :         }
    1810           0 :     }
    1811           0 : }
    1812             : 
    1813             : 
    1814           0 : void Content::notifyDocumentClosed()
    1815             : {
    1816           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1817             : 
    1818           0 :     m_eState = DEAD;
    1819             : 
    1820             :     // @@@ anything else to reset or such?
    1821             : 
    1822             :     // callback follows!
    1823           0 :     aGuard.clear();
    1824             : 
    1825             :     // Propagate destruction to content event listeners
    1826             :     // Remove this from provider's content list.
    1827           0 :     deleted();
    1828           0 : }
    1829             : 
    1830             : 
    1831             : uno::Reference< ucb::XContent >
    1832           0 : Content::queryChildContent( const OUString & rRelativeChildUri )
    1833             : {
    1834           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1835             : 
    1836           0 :     const OUString aMyId = getIdentifier()->getContentIdentifier();
    1837           0 :     OUStringBuffer aBuf( aMyId );
    1838           0 :     if ( !aMyId.endsWith("/") )
    1839           0 :         aBuf.appendAscii( "/" );
    1840           0 :     if ( !rRelativeChildUri.startsWith("/") )
    1841           0 :         aBuf.append( rRelativeChildUri );
    1842             :     else
    1843           0 :         aBuf.append( rRelativeChildUri.copy( 1 ) );
    1844             : 
    1845             :     uno::Reference< ucb::XContentIdentifier > xChildId
    1846           0 :         = new ::ucbhelper::ContentIdentifier( aBuf.makeStringAndClear() );
    1847             : 
    1848           0 :     uno::Reference< ucb::XContent > xChild;
    1849             :     try
    1850             :     {
    1851           0 :         xChild = m_pProvider->queryContent( xChildId );
    1852             :     }
    1853           0 :     catch ( ucb::IllegalIdentifierException const & )
    1854             :     {
    1855             :         // handled below.
    1856             :     }
    1857             : 
    1858             :     OSL_ENSURE( xChild.is(),
    1859             :                 "Content::queryChildContent - unable to create child content!" );
    1860           0 :     return xChild;
    1861             : }
    1862             : 
    1863             : 
    1864           0 : void Content::notifyChildRemoved( const OUString & rRelativeChildUri )
    1865             : {
    1866           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1867             : 
    1868             :     // Ugly! Need to create child content object, just to fill event properly.
    1869             :     uno::Reference< ucb::XContent > xChild
    1870           0 :         = queryChildContent( rRelativeChildUri );
    1871             : 
    1872           0 :     if ( xChild.is() )
    1873             :     {
    1874             :         // callback follows!
    1875           0 :         aGuard.clear();
    1876             : 
    1877             :         // Notify "REMOVED" event.
    1878             :         ucb::ContentEvent aEvt(
    1879             :             static_cast< cppu::OWeakObject * >( this ),
    1880             :             ucb::ContentAction::REMOVED,
    1881             :             xChild,
    1882           0 :             getIdentifier() );
    1883           0 :         notifyContentEvent( aEvt );
    1884           0 :     }
    1885           0 : }
    1886             : 
    1887             : 
    1888           0 : void Content::notifyChildInserted( const OUString & rRelativeChildUri )
    1889             : {
    1890           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1891             : 
    1892             :     // Ugly! Need to create child content object, just to fill event properly.
    1893             :     uno::Reference< ucb::XContent > xChild
    1894           0 :         = queryChildContent( rRelativeChildUri );
    1895             : 
    1896           0 :     if ( xChild.is() )
    1897             :     {
    1898             :         // callback follows!
    1899           0 :         aGuard.clear();
    1900             : 
    1901             :         // Notify "INSERTED" event.
    1902             :         ucb::ContentEvent aEvt(
    1903             :             static_cast< cppu::OWeakObject * >( this ),
    1904             :             ucb::ContentAction::INSERTED,
    1905             :             xChild,
    1906           0 :             getIdentifier() );
    1907           0 :         notifyContentEvent( aEvt );
    1908           0 :     }
    1909           0 : }
    1910             : 
    1911             : 
    1912           0 : void Content::transfer(
    1913             :             const ucb::TransferInfo& rInfo,
    1914             :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1915             :     throw( uno::Exception )
    1916             : {
    1917           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1918             : 
    1919             :     // Persistent?
    1920           0 :     if ( m_eState != PERSISTENT )
    1921             :     {
    1922             :         ucbhelper::cancelCommandExecution(
    1923             :             uno::makeAny( ucb::UnsupportedCommandException(
    1924             :                                 OUString( "Not persistent!" ),
    1925             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1926           0 :             xEnv );
    1927             :         // Unreachable
    1928             :     }
    1929             : 
    1930             :     // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
    1931             : 
    1932           0 :     if ( ( rInfo.SourceURL.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
    1933             :     {
    1934             :         // Invaild length (to short).
    1935             :         ucbhelper::cancelCommandExecution(
    1936             :             uno::makeAny( ucb::InteractiveBadTransferURLException(
    1937             :                             OUString(),
    1938             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
    1939           0 :             xEnv );
    1940             :         // Unreachable
    1941             :     }
    1942             : 
    1943             :     OUString aScheme
    1944             :         = rInfo.SourceURL.copy( 0, TDOC_URL_SCHEME_LENGTH + 2 )
    1945           0 :             .toAsciiLowerCase();
    1946           0 :     if ( aScheme != TDOC_URL_SCHEME ":/" )
    1947             :     {
    1948             :         // Invalid scheme.
    1949             :         ucbhelper::cancelCommandExecution(
    1950             :             uno::makeAny( ucb::InteractiveBadTransferURLException(
    1951             :                             OUString(),
    1952             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
    1953           0 :             xEnv );
    1954             :         // Unreachable
    1955             :     }
    1956             : 
    1957             :     // Does source URI describe a tdoc folder or stream?
    1958           0 :     Uri aSourceUri( rInfo.SourceURL );
    1959           0 :     if ( !aSourceUri.isValid() )
    1960             :     {
    1961             :         ucbhelper::cancelCommandExecution(
    1962             :             uno::makeAny( lang::IllegalArgumentException(
    1963             :                                 OUString( "Invalid source URI! Syntax!" ),
    1964             :                                 static_cast< cppu::OWeakObject * >( this ),
    1965             :                                 -1 ) ),
    1966           0 :             xEnv );
    1967             :         // Unreachable
    1968             :     }
    1969             : 
    1970           0 :     if ( aSourceUri.isRoot() || aSourceUri.isDocument() )
    1971             :     {
    1972             :         ucbhelper::cancelCommandExecution(
    1973             :             uno::makeAny( lang::IllegalArgumentException(
    1974             :                                 OUString( "Invalid source URI! "
    1975             :                                     "Must describe a folder or stream!" ),
    1976             :                                 static_cast< cppu::OWeakObject * >( this ),
    1977             :                                 -1 ) ),
    1978           0 :             xEnv );
    1979             :         // Unreachable
    1980             :     }
    1981             : 
    1982             :     // Is source not a parent of me / not me?
    1983           0 :     OUString aId = m_xIdentifier->getContentIdentifier();
    1984           0 :     sal_Int32 nPos = aId.lastIndexOf( '/' );
    1985           0 :     if ( nPos != ( aId.getLength() - 1 ) )
    1986             :     {
    1987             :         // No trailing slash found. Append.
    1988           0 :         aId += "/";
    1989             :     }
    1990             : 
    1991           0 :     if ( rInfo.SourceURL.getLength() <= aId.getLength() )
    1992             :     {
    1993           0 :         if ( aId.compareTo(
    1994           0 :                 rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
    1995             :         {
    1996             :             uno::Any aProps
    1997             :                 = uno::makeAny(beans::PropertyValue(
    1998             :                                       OUString( "Uri"),
    1999             :                                       -1,
    2000             :                                       uno::makeAny( rInfo.SourceURL ),
    2001           0 :                                       beans::PropertyState_DIRECT_VALUE));
    2002             :             ucbhelper::cancelCommandExecution(
    2003             :                 ucb::IOErrorCode_RECURSIVE,
    2004             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2005             :                 xEnv,
    2006             :                 OUString( "Target is equal to or is a child of source!" ),
    2007           0 :                 this );
    2008             :             // Unreachable
    2009             :         }
    2010             :     }
    2011             : 
    2012             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2013           0 :     if ( m_aProps.getType() == DOCUMENT )
    2014             :     {
    2015           0 :         bool bOK = false;
    2016             : 
    2017             :         uno::Reference< embed::XStorage > xStorage
    2018             :             = m_pProvider->queryStorage(
    2019           0 :                 aSourceUri.getParentUri(), READ_WRITE_NOCREATE );
    2020           0 :         if ( xStorage.is() )
    2021             :         {
    2022             :             try
    2023             :             {
    2024           0 :                 if ( xStorage->isStreamElement( aSourceUri.getDecodedName() ) )
    2025             :                 {
    2026             :                     ucbhelper::cancelCommandExecution(
    2027             :                         uno::makeAny( lang::IllegalArgumentException(
    2028             :                                         OUString( "Invalid source URI! "
    2029             :                                             "Streams cannot be created as "
    2030             :                                             "children of document root!" ),
    2031             :                                         static_cast< cppu::OWeakObject * >(
    2032             :                                             this ),
    2033             :                                         -1 ) ),
    2034           0 :                         xEnv );
    2035             :                     // Unreachable
    2036             :                 }
    2037           0 :                 bOK = true;
    2038             :             }
    2039           0 :             catch ( container::NoSuchElementException const & )
    2040             :             {
    2041             :                 // handled below.
    2042             :             }
    2043           0 :             catch ( lang::IllegalArgumentException const & )
    2044             :             {
    2045             :                 // handled below.
    2046             :             }
    2047           0 :             catch ( embed::InvalidStorageException const & )
    2048             :             {
    2049             :                 // handled below.
    2050             :             }
    2051             :         }
    2052             : 
    2053           0 :         if ( !bOK )
    2054             :         {
    2055             :             ucbhelper::cancelCommandExecution(
    2056             :                 uno::makeAny( lang::IllegalArgumentException(
    2057             :                                     OUString( "Invalid source URI! "
    2058             :                                         "Unabale to determine source type!" ),
    2059             :                                     static_cast< cppu::OWeakObject * >( this ),
    2060             :                                     -1 ) ),
    2061           0 :                 xEnv );
    2062             :             // Unreachable
    2063           0 :         }
    2064             :     }
    2065             : #endif
    2066             : 
    2067             : 
    2068             :     // Copy data.
    2069             : 
    2070             : 
    2071           0 :     OUString aNewName( !rInfo.NewTitle.isEmpty()
    2072             :                                 ? rInfo.NewTitle
    2073           0 :                                 : aSourceUri.getDecodedName() );
    2074             : 
    2075           0 :     if ( !copyData( aSourceUri, aNewName ) )
    2076             :     {
    2077             :         uno::Any aProps
    2078             :             = uno::makeAny(
    2079             :                      beans::PropertyValue(
    2080             :                          OUString( "Uri"),
    2081             :                          -1,
    2082             :                          uno::makeAny( rInfo.SourceURL ),
    2083           0 :                          beans::PropertyState_DIRECT_VALUE));
    2084             :         ucbhelper::cancelCommandExecution(
    2085             :             ucb::IOErrorCode_CANT_WRITE,
    2086             :             uno::Sequence< uno::Any >(&aProps, 1),
    2087             :             xEnv,
    2088             :             OUString( "Cannot copy data!"  ),
    2089           0 :             this );
    2090             :         // Unreachable
    2091             :     }
    2092             : 
    2093             : 
    2094             :     // Copy own and all children's Additional Core Properties.
    2095             : 
    2096             : 
    2097           0 :     OUString aTargetUri = m_xIdentifier->getContentIdentifier();
    2098           0 :     if ( ( aTargetUri.lastIndexOf( '/' ) + 1 ) != aTargetUri.getLength() )
    2099           0 :         aTargetUri += "/";
    2100             : 
    2101           0 :     if ( !rInfo.NewTitle.isEmpty() )
    2102           0 :         aTargetUri += ::ucb_impl::urihelper::encodeSegment( rInfo.NewTitle );
    2103             :     else
    2104           0 :         aTargetUri += aSourceUri.getName();
    2105             : 
    2106           0 :     if ( !copyAdditionalPropertySet(
    2107           0 :             aSourceUri.getUri(), aTargetUri, true ) )
    2108             :     {
    2109             :         uno::Any aProps
    2110             :             = uno::makeAny(
    2111             :                      beans::PropertyValue(
    2112             :                          OUString( "Uri"),
    2113             :                          -1,
    2114             :                          uno::makeAny( rInfo.SourceURL ),
    2115           0 :                          beans::PropertyState_DIRECT_VALUE));
    2116             :         ucbhelper::cancelCommandExecution(
    2117             :             ucb::IOErrorCode_CANT_WRITE,
    2118             :             uno::Sequence< uno::Any >(&aProps, 1),
    2119             :             xEnv,
    2120             :             OUString( "Cannot copy additional properties!"  ),
    2121           0 :             this );
    2122             :         // Unreachable
    2123             :     }
    2124             : 
    2125             : 
    2126             :     // Propagate new content.
    2127             : 
    2128             : 
    2129           0 :     rtl::Reference< Content > xTarget;
    2130             :     try
    2131             :     {
    2132             :         uno::Reference< ucb::XContentIdentifier > xTargetId
    2133           0 :             = new ::ucbhelper::ContentIdentifier( aTargetUri );
    2134             : 
    2135             :         // Note: The static cast is okay here, because its sure that
    2136             :         //       m_xProvider is always the WebDAVContentProvider.
    2137           0 :         xTarget = static_cast< Content * >(
    2138           0 :             m_pProvider->queryContent( xTargetId ).get() );
    2139             : 
    2140             :     }
    2141           0 :     catch ( ucb::IllegalIdentifierException const & )
    2142             :     {
    2143             :         // queryContent
    2144             :     }
    2145             : 
    2146           0 :     if ( !xTarget.is() )
    2147             :     {
    2148             :         uno::Any aProps
    2149             :             = uno::makeAny(beans::PropertyValue(
    2150             :                                   OUString( "Uri"),
    2151             :                                   -1,
    2152             :                                   uno::makeAny( aTargetUri ),
    2153           0 :                                   beans::PropertyState_DIRECT_VALUE));
    2154             :         ucbhelper::cancelCommandExecution(
    2155             :             ucb::IOErrorCode_CANT_READ,
    2156             :             uno::Sequence< uno::Any >(&aProps, 1),
    2157             :             xEnv,
    2158             :             OUString( "Cannot instanciate target object!" ),
    2159           0 :             this );
    2160             :         // Unreachable
    2161             :     }
    2162             : 
    2163             :     // Announce transferred content in its new folder.
    2164           0 :     xTarget->inserted();
    2165             : 
    2166             : 
    2167             :     // Remove source, if requested
    2168             : 
    2169             : 
    2170           0 :     if ( rInfo.MoveData )
    2171             :     {
    2172           0 :         rtl::Reference< Content > xSource;
    2173             :         try
    2174             :         {
    2175             :             uno::Reference< ucb::XContentIdentifier >
    2176           0 :                 xSourceId = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
    2177             : 
    2178             :             // Note: The static cast is okay here, because its sure
    2179             :             //       that m_xProvider is always the ContentProvider.
    2180           0 :             xSource = static_cast< Content * >(
    2181           0 :                 m_xProvider->queryContent( xSourceId ).get() );
    2182             :         }
    2183           0 :         catch ( ucb::IllegalIdentifierException const & )
    2184             :         {
    2185             :             // queryContent
    2186             :         }
    2187             : 
    2188           0 :         if ( !xSource.is() )
    2189             :         {
    2190             :             uno::Any aProps
    2191             :                 = uno::makeAny(beans::PropertyValue(
    2192             :                                       OUString( "Uri"),
    2193             :                                       -1,
    2194             :                                       uno::makeAny( rInfo.SourceURL ),
    2195           0 :                                       beans::PropertyState_DIRECT_VALUE));
    2196             :             ucbhelper::cancelCommandExecution(
    2197             :                 ucb::IOErrorCode_CANT_READ,
    2198             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2199             :                 xEnv,
    2200             :                 OUString( "Cannot instanciate target object!" ),
    2201           0 :                 this );
    2202             :             // Unreachable
    2203             :         }
    2204             : 
    2205             :         // Propagate destruction (recursively).
    2206           0 :         xSource->destroy( sal_True, xEnv );
    2207             : 
    2208             :         // Remove all persistent data of source and its children.
    2209           0 :         if ( !xSource->removeData() )
    2210             :         {
    2211             :             uno::Any aProps
    2212             :                 = uno::makeAny(
    2213             :                          beans::PropertyValue(
    2214             :                              OUString( "Uri"),
    2215             :                              -1,
    2216             :                              uno::makeAny( rInfo.SourceURL ),
    2217           0 :                              beans::PropertyState_DIRECT_VALUE));
    2218             :             ucbhelper::cancelCommandExecution(
    2219             :                 ucb::IOErrorCode_CANT_WRITE,
    2220             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2221             :                 xEnv,
    2222             :                 OUString( "Cannot remove persistent data of source object!" ),
    2223           0 :                 this );
    2224             :             // Unreachable
    2225             :         }
    2226             : 
    2227             :         // Remove own and all children's Additional Core Properties.
    2228           0 :         if ( !xSource->removeAdditionalPropertySet( true ) )
    2229             :         {
    2230             :             uno::Any aProps
    2231             :                 = uno::makeAny(
    2232             :                          beans::PropertyValue(
    2233             :                              OUString( "Uri"),
    2234             :                              -1,
    2235             :                              uno::makeAny( rInfo.SourceURL ),
    2236           0 :                              beans::PropertyState_DIRECT_VALUE));
    2237             :             ucbhelper::cancelCommandExecution(
    2238             :                 ucb::IOErrorCode_CANT_WRITE,
    2239             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2240             :                 xEnv,
    2241             :                 OUString( "Cannot remove additional properties of source object!" ),
    2242           0 :                 this );
    2243             :             // Unreachable
    2244           0 :         }
    2245             : 
    2246           0 :     } // rInfo.MoveData
    2247           0 : }
    2248             : 
    2249             : 
    2250             : //static
    2251           0 : bool Content::hasData( ContentProvider* pProvider, const Uri & rUri )
    2252             : {
    2253           0 :     if ( rUri.isRoot() )
    2254             :     {
    2255           0 :         return true; // root has no storage
    2256             :     }
    2257           0 :     else if ( rUri.isDocument() )
    2258             :     {
    2259             :         uno::Reference< embed::XStorage > xStorage
    2260           0 :             = pProvider->queryStorage( rUri.getUri(), READ );
    2261           0 :         return xStorage.is();
    2262             :     }
    2263             :     else
    2264             :     {
    2265             :         // folder or stream
    2266             : 
    2267             :         // Ask parent storage. In case that rUri describes a stream,
    2268             :         // ContentProvider::queryStorage( rUri ) would return null.
    2269             : 
    2270             :         uno::Reference< embed::XStorage > xStorage
    2271           0 :             = pProvider->queryStorage( rUri.getParentUri(), READ );
    2272             : 
    2273           0 :         if ( !xStorage.is() )
    2274           0 :             return false;
    2275             : 
    2276             :         uno::Reference< container::XNameAccess > xParentNA(
    2277           0 :             xStorage, uno::UNO_QUERY );
    2278             : 
    2279             :         OSL_ENSURE( xParentNA.is(), "Got no css.container.XNameAccess!" );
    2280             : 
    2281           0 :         return xParentNA->hasByName( rUri.getDecodedName() );
    2282             :     }
    2283             : }
    2284             : 
    2285             : 
    2286             : //static
    2287           0 : bool Content::loadData( ContentProvider* pProvider,
    2288             :                         const Uri & rUri,
    2289             :                         ContentProperties& rProps )
    2290             : {
    2291           0 :     if ( rUri.isRoot() ) // root has no storage, but can always be created
    2292             :     {
    2293             :         rProps
    2294           0 :             = ContentProperties(
    2295           0 :                 ROOT, pProvider->queryStorageTitle( rUri.getUri() ) );
    2296             :     }
    2297           0 :     else if ( rUri.isDocument() ) // document must have storage
    2298             :     {
    2299             :         uno::Reference< embed::XStorage > xStorage
    2300           0 :             = pProvider->queryStorage( rUri.getUri(), READ );
    2301             : 
    2302           0 :         if ( !xStorage.is() )
    2303           0 :             return false;
    2304             : 
    2305             :         rProps
    2306           0 :             = ContentProperties(
    2307           0 :                 DOCUMENT, pProvider->queryStorageTitle( rUri.getUri() ) );
    2308             :     }
    2309             :     else // stream or folder; stream has no storage; folder has storage
    2310             :     {
    2311             :         uno::Reference< embed::XStorage > xStorage
    2312           0 :             = pProvider->queryStorage( rUri.getParentUri(), READ );
    2313             : 
    2314           0 :         if ( !xStorage.is() )
    2315           0 :             return false;
    2316             : 
    2317             :         // Check whether exists at all, is stream or folder
    2318             :         try
    2319             :         {
    2320             :             // return: true  -> folder
    2321             :             // return: false -> stream
    2322             :             // NoSuchElementException -> neither folder nor stream
    2323             :             bool bIsFolder
    2324           0 :                 = xStorage->isStorageElement( rUri.getDecodedName() );
    2325             : 
    2326             :             rProps
    2327           0 :                 = ContentProperties(
    2328             :                     bIsFolder ? FOLDER : STREAM,
    2329           0 :                     pProvider->queryStorageTitle( rUri.getUri() ) );
    2330             :         }
    2331           0 :         catch ( container::NoSuchElementException const & )
    2332             :         {
    2333             :             // there is no element with such name
    2334             :             //OSL_ENSURE( false, "Caught NoSuchElementException!" );
    2335           0 :             return false;
    2336             :         }
    2337           0 :         catch ( lang::IllegalArgumentException const & )
    2338             :         {
    2339             :             // an illegal argument is provided
    2340             :             OSL_FAIL( "Caught IllegalArgumentException!" );
    2341           0 :             return false;
    2342             :         }
    2343           0 :         catch ( embed::InvalidStorageException const & )
    2344             :         {
    2345             :             // this storage is in invalid state for any reason
    2346             :             OSL_FAIL( "Caught InvalidStorageException!" );
    2347           0 :             return false;
    2348           0 :         }
    2349             :     }
    2350           0 :     return true;
    2351             : }
    2352             : 
    2353             : 
    2354           0 : bool Content::storeData( const uno::Reference< io::XInputStream >& xData,
    2355             :                          const uno::Reference<
    2356             :                             ucb::XCommandEnvironment >& xEnv )
    2357             :     throw ( ucb::CommandFailedException,
    2358             :             task::DocumentPasswordRequest )
    2359             : {
    2360           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2361             : 
    2362           0 :     ContentType eType = m_aProps.getType();
    2363           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2364             :     {
    2365             :         OSL_FAIL( "storeData not supported by root and documents!" );
    2366           0 :         return false;
    2367             :     }
    2368             : 
    2369           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    2370             : 
    2371           0 :     if ( eType == FOLDER )
    2372             :     {
    2373             :         uno::Reference< embed::XStorage > xStorage
    2374           0 :             = m_pProvider->queryStorage( aUri.getUri(), READ_WRITE_CREATE );
    2375             : 
    2376           0 :         if ( !xStorage.is() )
    2377           0 :             return false;
    2378             : 
    2379             :         uno::Reference< beans::XPropertySet > xPropSet(
    2380           0 :             xStorage, uno::UNO_QUERY );
    2381             :         OSL_ENSURE( xPropSet.is(),
    2382             :                     "Content::storeData - Got no XPropertySet interface!" );
    2383           0 :         if ( !xPropSet.is() )
    2384           0 :             return false;
    2385             : 
    2386             :         try
    2387             :         {
    2388             :             // According to MBA, if no mediatype is set, folder and all
    2389             :             // its contents will be lost on save of the document!!!
    2390           0 :             xPropSet->setPropertyValue(
    2391             :                 OUString(  "MediaType"  ),
    2392             :                 uno::makeAny(
    2393             :                     OUString(                        // @@@ better mediatype
    2394           0 :                         "application/binary"  ) ) );
    2395             :         }
    2396           0 :         catch ( beans::UnknownPropertyException const & )
    2397             :         {
    2398             :             OSL_FAIL( "Property MediaType not supported!" );
    2399           0 :             return false;
    2400             :         }
    2401           0 :         catch ( beans::PropertyVetoException const & )
    2402             :         {
    2403             :             OSL_FAIL( "Caught PropertyVetoException!" );
    2404           0 :             return false;
    2405             :         }
    2406           0 :         catch ( lang::IllegalArgumentException const & )
    2407             :         {
    2408             :             OSL_FAIL( "Caught IllegalArgumentException!" );
    2409           0 :             return false;
    2410             :         }
    2411           0 :         catch ( lang::WrappedTargetException const & )
    2412             :         {
    2413             :             OSL_FAIL( "Caught WrappedTargetException!" );
    2414           0 :             return false;
    2415             :         }
    2416             : 
    2417           0 :         if ( !commitStorage( xStorage ) )
    2418           0 :             return false;
    2419             :     }
    2420           0 :     else if ( eType == STREAM )
    2421             :     {
    2422             :         // stream
    2423             : 
    2424             :         // Important: Parent storage and output stream must be kept alive until
    2425             :         //            changes have been committed!
    2426             :         uno::Reference< embed::XStorage > xStorage
    2427             :             = m_pProvider->queryStorage(
    2428           0 :                 aUri.getParentUri(), READ_WRITE_CREATE );
    2429           0 :         uno::Reference< io::XOutputStream > xOut;
    2430             : 
    2431           0 :         if ( !xStorage.is() )
    2432           0 :             return false;
    2433             : 
    2434           0 :         if ( xData.is() )
    2435             :         {
    2436             :             // May throw CommandFailedException, DocumentPasswordRequest!
    2437           0 :             xOut = getTruncatedOutputStream( xEnv );
    2438             : 
    2439             :             OSL_ENSURE( xOut.is(), "No target data stream!" );
    2440             : 
    2441             :             try
    2442             :             {
    2443           0 :                 uno::Sequence< sal_Int8 > aBuffer;
    2444           0 :                 sal_Int32 nRead = xData->readSomeBytes( aBuffer, 65536 );
    2445             : 
    2446           0 :                 while ( nRead > 0 )
    2447             :                 {
    2448           0 :                     aBuffer.realloc( nRead );
    2449           0 :                     xOut->writeBytes( aBuffer );
    2450           0 :                     aBuffer.realloc( 0 );
    2451           0 :                     nRead = xData->readSomeBytes( aBuffer, 65536 );
    2452             :                 }
    2453             : 
    2454           0 :                 closeOutputStream( xOut );
    2455             :             }
    2456           0 :             catch ( io::NotConnectedException const & )
    2457             :             {
    2458             :                 // readSomeBytes, writeBytes
    2459             :                 OSL_FAIL( "Caught NotConnectedException!" );
    2460           0 :                 closeOutputStream( xOut );
    2461           0 :                 return false;
    2462             :             }
    2463           0 :             catch ( io::BufferSizeExceededException const & )
    2464             :             {
    2465             :                 // readSomeBytes, writeBytes
    2466             :                 OSL_FAIL( "Caught BufferSizeExceededException!" );
    2467           0 :                 closeOutputStream( xOut );
    2468           0 :                 return false;
    2469             :             }
    2470           0 :             catch ( io::IOException const & )
    2471             :             {
    2472             :                 // readSomeBytes, writeBytes
    2473             :                 OSL_FAIL( "Caught IOException!" );
    2474           0 :                 closeOutputStream( xOut );
    2475           0 :                 return false;
    2476             :             }
    2477           0 :             catch ( ... )
    2478             :             {
    2479           0 :                 closeOutputStream( xOut );
    2480           0 :                 throw;
    2481             :             }
    2482             :         }
    2483             : 
    2484             :         // Commit changes.
    2485           0 :         if ( !commitStorage( xStorage ) )
    2486           0 :             return false;
    2487             :     }
    2488             :     else
    2489             :     {
    2490             :         OSL_FAIL( "Unknown content type!" );
    2491           0 :         return false;
    2492             :     }
    2493           0 :     return true;
    2494             : }
    2495             : 
    2496             : 
    2497           0 : bool Content::renameData(
    2498             :             const uno::Reference< ucb::XContentIdentifier >& xOldId,
    2499             :             const uno::Reference< ucb::XContentIdentifier >& xNewId )
    2500             : {
    2501           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2502             : 
    2503           0 :     ContentType eType = m_aProps.getType();
    2504           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2505             :     {
    2506             :         OSL_FAIL( "renameData not supported by root and documents!" );
    2507           0 :         return false;
    2508             :     }
    2509             : 
    2510           0 :     Uri aOldUri( xOldId->getContentIdentifier() );
    2511             :     uno::Reference< embed::XStorage > xStorage
    2512             :         = m_pProvider->queryStorage(
    2513           0 :             aOldUri.getParentUri(), READ_WRITE_NOCREATE );
    2514             : 
    2515           0 :     if ( !xStorage.is() )
    2516           0 :         return false;
    2517             : 
    2518             :     try
    2519             :     {
    2520           0 :         Uri aNewUri( xNewId->getContentIdentifier() );
    2521           0 :         xStorage->renameElement(
    2522           0 :             aOldUri.getDecodedName(), aNewUri.getDecodedName() );
    2523             :     }
    2524           0 :     catch ( embed::InvalidStorageException const & )
    2525             :     {
    2526             :         // this storage is in invalid state for eny reason
    2527             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2528           0 :         return false;
    2529             :     }
    2530           0 :     catch ( lang::IllegalArgumentException const & )
    2531             :     {
    2532             :         // an illegal argument is provided
    2533             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2534           0 :         return false;
    2535             :     }
    2536           0 :     catch ( container::NoSuchElementException const & )
    2537             :     {
    2538             :         // there is no element with old name in this storage
    2539             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2540           0 :         return false;
    2541             :     }
    2542           0 :     catch ( container::ElementExistException const & )
    2543             :     {
    2544             :         // an element with new name already exists in this storage
    2545             :         OSL_FAIL( "Caught ElementExistException!" );
    2546           0 :         return false;
    2547             :     }
    2548           0 :     catch ( io::IOException const & )
    2549             :     {
    2550             :         // in case of io errors during renaming
    2551             :         OSL_FAIL( "Caught IOException!" );
    2552           0 :         return false;
    2553             :     }
    2554           0 :     catch ( embed::StorageWrappedTargetException const & )
    2555             :     {
    2556             :         // wraps other exceptions
    2557             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2558           0 :         return false;
    2559             :     }
    2560             : 
    2561           0 :     return commitStorage( xStorage );
    2562             : }
    2563             : 
    2564             : 
    2565           0 : bool Content::removeData()
    2566             : {
    2567           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2568             : 
    2569           0 :     ContentType eType = m_aProps.getType();
    2570           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2571             :     {
    2572             :         OSL_FAIL( "removeData not supported by root and documents!" );
    2573           0 :         return false;
    2574             :     }
    2575             : 
    2576           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    2577             :     uno::Reference< embed::XStorage > xStorage
    2578             :         = m_pProvider->queryStorage(
    2579           0 :             aUri.getParentUri(), READ_WRITE_NOCREATE );
    2580             : 
    2581           0 :     if ( !xStorage.is() )
    2582           0 :         return false;
    2583             : 
    2584             :     try
    2585             :     {
    2586           0 :         xStorage->removeElement( aUri.getDecodedName() );
    2587             :     }
    2588           0 :     catch ( embed::InvalidStorageException const & )
    2589             :     {
    2590             :         // this storage is in invalid state for eny reason
    2591             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2592           0 :         return false;
    2593             :     }
    2594           0 :     catch ( lang::IllegalArgumentException const & )
    2595             :     {
    2596             :         // an illegal argument is provided
    2597             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2598           0 :         return false;
    2599             :     }
    2600           0 :     catch ( container::NoSuchElementException const & )
    2601             :     {
    2602             :         // there is no element with this name in this storage
    2603             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2604           0 :         return false;
    2605             :     }
    2606           0 :     catch ( io::IOException const & )
    2607             :     {
    2608             :         // in case of io errors during renaming
    2609             :         OSL_FAIL( "Caught IOException!" );
    2610           0 :         return false;
    2611             :     }
    2612           0 :     catch ( embed::StorageWrappedTargetException const & )
    2613             :     {
    2614             :         // wraps other exceptions
    2615             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2616           0 :         return false;
    2617             :     }
    2618             : 
    2619           0 :     return commitStorage( xStorage );
    2620             : }
    2621             : 
    2622             : 
    2623           0 : bool Content::copyData( const Uri & rSourceUri, const OUString & rNewName )
    2624             : {
    2625           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2626             : 
    2627           0 :     ContentType eType = m_aProps.getType();
    2628           0 :     if ( ( eType == ROOT ) || ( eType == STREAM ) )
    2629             :     {
    2630             :         OSL_FAIL( "copyData not supported by root and streams!" );
    2631           0 :         return false;
    2632             :     }
    2633             : 
    2634           0 :     Uri aDestUri( m_xIdentifier->getContentIdentifier() );
    2635             :     uno::Reference< embed::XStorage > xDestStorage
    2636           0 :         = m_pProvider->queryStorage( aDestUri.getUri(), READ_WRITE_NOCREATE );
    2637             : 
    2638           0 :     if ( !xDestStorage.is() )
    2639           0 :         return false;
    2640             : 
    2641             :     uno::Reference< embed::XStorage > xSourceStorage
    2642           0 :         = m_pProvider->queryStorage( rSourceUri.getParentUri(), READ );
    2643             : 
    2644           0 :     if ( !xSourceStorage.is() )
    2645           0 :         return false;
    2646             : 
    2647             :     try
    2648             :     {
    2649           0 :         xSourceStorage->copyElementTo( rSourceUri.getDecodedName(),
    2650             :                                        xDestStorage,
    2651           0 :                                        rNewName );
    2652             :     }
    2653           0 :     catch ( embed::InvalidStorageException const & )
    2654             :     {
    2655             :         // this storage is in invalid state for eny reason
    2656             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2657           0 :         return false;
    2658             :     }
    2659           0 :     catch ( lang::IllegalArgumentException const & )
    2660             :     {
    2661             :         // an illegal argument is provided
    2662             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2663           0 :         return false;
    2664             :     }
    2665           0 :     catch ( container::NoSuchElementException const & )
    2666             :     {
    2667             :         // there is no element with this name in this storage
    2668             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2669           0 :         return false;
    2670             :     }
    2671           0 :     catch ( container::ElementExistException const & )
    2672             :     {
    2673             :         // there is no element with this name in this storage
    2674             :         OSL_FAIL( "Caught ElementExistException!" );
    2675           0 :         return false;
    2676             :     }
    2677           0 :     catch ( io::IOException const & )
    2678             :     {
    2679             :         // in case of io errors during renaming
    2680             :         OSL_FAIL( "Caught IOException!" );
    2681           0 :         return false;
    2682             :     }
    2683           0 :     catch ( embed::StorageWrappedTargetException const & )
    2684             :     {
    2685             :         // wraps other exceptions
    2686             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2687           0 :         return false;
    2688             :     }
    2689             : 
    2690           0 :     return commitStorage( xDestStorage );
    2691             : }
    2692             : 
    2693             : 
    2694             : // static
    2695           0 : bool Content::commitStorage( const uno::Reference< embed::XStorage > & xStorage )
    2696             : {
    2697             :     // Commit changes
    2698           0 :     uno::Reference< embed::XTransactedObject > xTO( xStorage, uno::UNO_QUERY );
    2699             : 
    2700             :     OSL_ENSURE( xTO.is(),
    2701             :                 "Required interface css.embed.XTransactedObject missing!" );
    2702             :     try
    2703             :     {
    2704           0 :         xTO->commit();
    2705             :     }
    2706           0 :     catch ( io::IOException const & )
    2707             :     {
    2708             :         OSL_FAIL( "Caught IOException!" );
    2709           0 :         return false;
    2710             :     }
    2711           0 :     catch ( lang::WrappedTargetException const & )
    2712             :     {
    2713             :         OSL_FAIL( "Caught WrappedTargetException!" );
    2714           0 :         return false;
    2715             :     }
    2716             : 
    2717           0 :     return true;
    2718             : }
    2719             : 
    2720             : 
    2721             : // static
    2722           0 : bool Content::closeOutputStream(
    2723             :     const uno::Reference< io::XOutputStream > & xOut )
    2724             : {
    2725           0 :     if ( xOut.is() )
    2726             :     {
    2727             :         try
    2728             :         {
    2729           0 :             xOut->closeOutput();
    2730           0 :             return true;
    2731             :         }
    2732           0 :         catch ( io::NotConnectedException const & )
    2733             :         {
    2734             :             OSL_FAIL( "Caught NotConnectedException!" );
    2735             :         }
    2736           0 :         catch ( io::BufferSizeExceededException const & )
    2737             :         {
    2738             :             OSL_FAIL( "Caught BufferSizeExceededException!" );
    2739             :         }
    2740           0 :         catch ( io::IOException const & )
    2741             :         {
    2742             :             OSL_FAIL( "Caught IOException!" );
    2743             :         }
    2744             :     }
    2745           0 :     return false;
    2746             : }
    2747             : 
    2748             : 
    2749           0 : static OUString obtainPassword(
    2750             :         const OUString & rName,
    2751             :         task::PasswordRequestMode eMode,
    2752             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2753             :     throw ( ucb::CommandFailedException,
    2754             :             task::DocumentPasswordRequest )
    2755             : {
    2756             :     rtl::Reference< DocumentPasswordRequest > xRequest
    2757           0 :         = new DocumentPasswordRequest( eMode, rName );
    2758             : 
    2759           0 :     if ( xEnv.is() )
    2760             :     {
    2761             :         uno::Reference< task::XInteractionHandler > xIH
    2762           0 :             = xEnv->getInteractionHandler();
    2763           0 :         if ( xIH.is() )
    2764             :         {
    2765           0 :             xIH->handle( xRequest.get() );
    2766             : 
    2767             :             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
    2768           0 :                 = xRequest->getSelection();
    2769             : 
    2770           0 :             if ( xSelection.is() )
    2771             :             {
    2772             :                 // Handler handled the request.
    2773             :                 uno::Reference< task::XInteractionAbort > xAbort(
    2774           0 :                     xSelection.get(), uno::UNO_QUERY );
    2775           0 :                 if ( xAbort.is() )
    2776             :                 {
    2777             :                     throw ucb::CommandFailedException(
    2778             :                         OUString( "Abort requested by Interaction Handler."  ),
    2779             :                         uno::Reference< uno::XInterface >(),
    2780           0 :                         xRequest->getRequest() );
    2781             :                 }
    2782             : 
    2783             :                 uno::Reference< task::XInteractionPassword > xPassword(
    2784           0 :                     xSelection.get(), uno::UNO_QUERY );
    2785           0 :                 if ( xPassword.is() )
    2786             :                 {
    2787           0 :                     return xPassword->getPassword();
    2788             :                 }
    2789             : 
    2790             :                 // Unknown selection. Should never happen.
    2791             :                 throw ucb::CommandFailedException(
    2792             :                     OUString( "Interaction Handler selected unknown continuation!"  ),
    2793             :                     uno::Reference< uno::XInterface >(),
    2794           0 :                     xRequest->getRequest() );
    2795           0 :             }
    2796           0 :         }
    2797             :     }
    2798             : 
    2799             :     // No IH or IH did not handle exception.
    2800           0 :     task::DocumentPasswordRequest aRequest;
    2801           0 :     xRequest->getRequest() >>= aRequest;
    2802           0 :     throw aRequest;
    2803             : }
    2804             : 
    2805             : 
    2806           0 : uno::Reference< io::XInputStream > Content::getInputStream(
    2807             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2808             :     throw ( ucb::CommandFailedException,
    2809             :             task::DocumentPasswordRequest )
    2810             : {
    2811           0 :     OUString aUri;
    2812           0 :     OUString aPassword;
    2813           0 :     bool bPasswordRequested = false;
    2814             : 
    2815             :     {
    2816           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2817             : 
    2818             :         OSL_ENSURE( m_aProps.getType() == STREAM,
    2819             :                     "Content::getInputStream - content is no stream!" );
    2820             : 
    2821           0 :         aUri = Uri( m_xIdentifier->getContentIdentifier() ).getUri();
    2822             :     }
    2823             : 
    2824             :     for ( ;; )
    2825             :     {
    2826             :         try
    2827             :         {
    2828           0 :             osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2829             :             return uno::Reference< io::XInputStream >(
    2830           0 :                 m_pProvider->queryInputStream( aUri, aPassword ) );
    2831             :         }
    2832           0 :         catch ( packages::WrongPasswordException const & )
    2833             :         {
    2834             :             // Obtain (new) password.
    2835             :             aPassword
    2836           0 :                 = obtainPassword( aUri, /* @@@ find better title */
    2837             :                                   bPasswordRequested
    2838             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2839             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2840           0 :                                    xEnv );
    2841           0 :             bPasswordRequested = true;
    2842             :         }
    2843           0 :     }
    2844             : }
    2845             : 
    2846             : 
    2847           0 : static uno::Reference< io::XOutputStream > lcl_getTruncatedOutputStream(
    2848             :                 const OUString & rUri,
    2849             :                 ContentProvider * pProvider,
    2850             :                 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2851             :     throw ( ucb::CommandFailedException,
    2852             :             task::DocumentPasswordRequest )
    2853             : {
    2854           0 :     OUString aPassword;
    2855           0 :     bool bPasswordRequested = false;
    2856             :     for ( ;; )
    2857             :     {
    2858             :         try
    2859             :         {
    2860             :             return uno::Reference< io::XOutputStream >(
    2861             :                 pProvider->queryOutputStream(
    2862           0 :                     rUri, aPassword, true /* truncate */ ) );
    2863             :         }
    2864           0 :         catch ( packages::WrongPasswordException const & )
    2865             :         {
    2866             :             // Obtain (new) password.
    2867             :             aPassword
    2868           0 :                 = obtainPassword( rUri, /* @@@ find better title */
    2869             :                                   bPasswordRequested
    2870             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2871             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2872           0 :                                    xEnv );
    2873           0 :             bPasswordRequested = true;
    2874             :         }
    2875           0 :     }
    2876             : }
    2877             : 
    2878             : 
    2879           0 : uno::Reference< io::XOutputStream > Content::getTruncatedOutputStream(
    2880             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2881             :     throw ( ucb::CommandFailedException,
    2882             :             task::DocumentPasswordRequest )
    2883             : {
    2884             :     OSL_ENSURE( m_aProps.getType() == STREAM,
    2885             :                 "Content::getTruncatedOutputStream - content is no stream!" );
    2886             : 
    2887             :     return lcl_getTruncatedOutputStream(
    2888           0 :             Uri( m_xIdentifier->getContentIdentifier() ).getUri(),
    2889             :             m_pProvider,
    2890           0 :             xEnv );
    2891             : }
    2892             : 
    2893             : 
    2894           0 : uno::Reference< io::XStream > Content::getStream(
    2895             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2896             :     throw ( ucb::CommandFailedException,
    2897             :             task::DocumentPasswordRequest )
    2898             : {
    2899           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2900             : 
    2901             :     OSL_ENSURE( m_aProps.getType() == STREAM,
    2902             :                 "Content::getStream - content is no stream!" );
    2903             : 
    2904           0 :     OUString aUri( Uri( m_xIdentifier->getContentIdentifier() ).getUri() );
    2905           0 :     OUString aPassword;
    2906           0 :     bool bPasswordRequested = false;
    2907             :     for ( ;; )
    2908             :     {
    2909             :         try
    2910             :         {
    2911             :             return uno::Reference< io::XStream >(
    2912             :                 m_pProvider->queryStream(
    2913           0 :                     aUri, aPassword, false /* no truncate */ ) );
    2914             :         }
    2915           0 :         catch ( packages::WrongPasswordException const & )
    2916             :         {
    2917             :             // Obtain (new) password.
    2918             :             aPassword
    2919           0 :                 = obtainPassword( aUri, /* @@@ find better title */
    2920             :                                   bPasswordRequested
    2921             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2922             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2923           0 :                                    xEnv );
    2924           0 :             bPasswordRequested = true;
    2925             :         }
    2926           0 :     }
    2927             : }
    2928             : 
    2929             : 
    2930             : 
    2931             : 
    2932             : // ContentProperties Implementation.
    2933             : 
    2934             : 
    2935             : 
    2936             : 
    2937             : uno::Sequence< ucb::ContentInfo >
    2938           0 : ContentProperties::getCreatableContentsInfo() const
    2939             : {
    2940           0 :     if ( isContentCreator() )
    2941             :     {
    2942           0 :         uno::Sequence< beans::Property > aProps( 1 );
    2943           0 :         aProps.getArray()[ 0 ] = beans::Property(
    2944             :                     OUString("Title"),
    2945             :                     -1,
    2946           0 :                     getCppuType( static_cast< const OUString * >( 0 ) ),
    2947           0 :                     beans::PropertyAttribute::BOUND );
    2948             : 
    2949             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2950           0 :         if ( getType() == DOCUMENT )
    2951             :         {
    2952             :             // streams cannot be created as direct children of document root
    2953           0 :             uno::Sequence< ucb::ContentInfo > aSeq( 1 );
    2954             : 
    2955             :             // Folder.
    2956           0 :             aSeq.getArray()[ 0 ].Type = TDOC_FOLDER_CONTENT_TYPE;
    2957           0 :             aSeq.getArray()[ 0 ].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
    2958           0 :             aSeq.getArray()[ 0 ].Properties = aProps;
    2959             : 
    2960           0 :             return aSeq;
    2961             :         }
    2962             :         else
    2963             :         {
    2964             : #endif
    2965           0 :             uno::Sequence< ucb::ContentInfo > aSeq( 2 );
    2966             : 
    2967             :             // Folder.
    2968           0 :             aSeq.getArray()[ 0 ].Type = TDOC_FOLDER_CONTENT_TYPE;
    2969           0 :             aSeq.getArray()[ 0 ].Attributes
    2970           0 :                 = ucb::ContentInfoAttribute::KIND_FOLDER;
    2971           0 :             aSeq.getArray()[ 0 ].Properties = aProps;
    2972             : 
    2973             :             // Stream.
    2974           0 :             aSeq.getArray()[ 1 ].Type = TDOC_STREAM_CONTENT_TYPE;
    2975           0 :             aSeq.getArray()[ 1 ].Attributes
    2976             :                 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
    2977           0 :                   | ucb::ContentInfoAttribute::KIND_DOCUMENT;
    2978           0 :             aSeq.getArray()[ 1 ].Properties = aProps;
    2979             : 
    2980           0 :             return aSeq;
    2981             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2982           0 :         }
    2983             : #endif
    2984             :     }
    2985             :     else
    2986             :     {
    2987             :         OSL_FAIL( "getCreatableContentsInfo called on non-contentcreator "
    2988             :                     "object!" );
    2989             : 
    2990           0 :         return uno::Sequence< ucb::ContentInfo >( 0 );
    2991             :     }
    2992             : }
    2993             : 
    2994             : 
    2995           0 : bool ContentProperties::isContentCreator() const
    2996             : {
    2997           0 :     return ( getType() == FOLDER ) || ( getType() == DOCUMENT );
    2998             : }
    2999             : 
    3000             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10