LCOV - code coverage report
Current view: top level - ucb/source/ucp/tdoc - tdoc_content.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 65 976 6.7 %
Date: 2015-06-13 12:38:46 Functions: 12 51 23.5 %
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         328 : 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         328 :     ContentProperties aProps;
     107         656 :     if ( !Content::loadData( pProvider,
     108         328 :                              Uri( Identifier->getContentIdentifier() ),
     109         656 :                              aProps ) )
     110           0 :         return 0;
     111             : 
     112         328 :     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         328 : 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         328 :   m_pProvider( pProvider )
     145             : {
     146         328 : }
     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         656 : Content::~Content()
     165             : {
     166         656 : }
     167             : 
     168             : 
     169             : 
     170             : // XInterface methods.
     171             : 
     172             : 
     173             : 
     174             : // virtual
     175        2195 : void SAL_CALL Content::acquire()
     176             :     throw( )
     177             : {
     178        2195 :     ContentImplHelper::acquire();
     179        2195 : }
     180             : 
     181             : 
     182             : // virtual
     183        2195 : void SAL_CALL Content::release()
     184             :     throw( )
     185             : {
     186        2195 :     ContentImplHelper::release();
     187        2195 : }
     188             : 
     189             : 
     190             : // virtual
     191         342 : uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
     192             :     throw ( uno::RuntimeException, std::exception )
     193             : {
     194         342 :     uno::Any aRet = ContentImplHelper::queryInterface( rType );
     195             : 
     196         342 :     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         342 :     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         328 : Content::getIdentifier()
     346             :     throw( uno::RuntimeException, std::exception )
     347             : {
     348             :     {
     349         328 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     350             : 
     351             :         // Transient?
     352         328 :         if ( m_eState == TRANSIENT )
     353             :         {
     354             :             // Transient contents have no identifier.
     355           0 :             return uno::Reference< ucb::XContentIdentifier >();
     356         328 :         }
     357             :     }
     358         328 :     return ContentImplHelper::getIdentifier();
     359             : }
     360             : 
     361             : 
     362             : 
     363             : // XCommandProcessor methods.
     364             : 
     365             : 
     366             : 
     367             : // virtual
     368         171 : 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         171 :     uno::Any aRet;
     377             : 
     378         171 :     if ( aCommand.Name == "getPropertyValues" )
     379             :     {
     380             : 
     381             :         // getPropertyValues
     382             : 
     383             : 
     384         171 :         uno::Sequence< beans::Property > Properties;
     385         171 :         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         171 :         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 :         bool bDeletePhysical = 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         171 :     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 :         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 instantiated 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.startsWith( aURL ) ) )
     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 : bool Content::exchangeIdentity(
     822             :             const uno::Reference< ucb::XContentIdentifier >& xNewId )
     823             : {
     824           0 :     if ( !xNewId.is() )
     825           0 :         return 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 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 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 instantiated 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 false;
     886             : 
     887           0 :                     ++it;
     888           0 :                 }
     889             :             }
     890           0 :             return true;
     891           0 :         }
     892             :     }
     893             : 
     894             :     OSL_FAIL( "Content::exchangeIdentity - "
     895             :                 "Panic! Cannot exchange identity!" );
     896           0 :     return 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         171 : 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         171 :         = new ::ucbhelper::PropertyValueSet( rxContext );
     943             : 
     944         171 :     sal_Int32 nCount = rProperties.getLength();
     945         171 :     if ( nCount )
     946             :     {
     947         171 :         uno::Reference< beans::XPropertySet > xAdditionalPropSet;
     948         171 :         bool bTriedToGetAdditionalPropSet = false;
     949             : 
     950         171 :         const beans::Property* pProps = rProperties.getConstArray();
     951         342 :         for ( sal_Int32 n = 0; n < nCount; ++n )
     952             :         {
     953         171 :             const beans::Property& rProp = pProps[ n ];
     954             : 
     955             :             // Process Core properties.
     956             : 
     957         171 :             if ( rProp.Name == "ContentType" )
     958             :             {
     959           0 :                 xRow->appendString ( rProp, rData.getContentType() );
     960             :             }
     961         171 :             else if ( rProp.Name == "Title" )
     962             :             {
     963           0 :                 xRow->appendString ( rProp, rData.getTitle() );
     964             :             }
     965         171 :             else if ( rProp.Name == "IsDocument" )
     966             :             {
     967           0 :                 xRow->appendBoolean( rProp, rData.getIsDocument() );
     968             :             }
     969         171 :             else if ( rProp.Name == "IsFolder" )
     970             :             {
     971           0 :                 xRow->appendBoolean( rProp, rData.getIsFolder() );
     972             :             }
     973         171 :             else if ( rProp.Name == "CreatableContentsInfo" )
     974             :             {
     975             :                 xRow->appendObject(
     976           0 :                     rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
     977             :             }
     978         171 :             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         171 :             else if ( rProp.Name == "DocumentModel" )
     991             :             {
     992             :                 // DocumentModel is only supported by documents.
     993         171 :                 ContentType eType = rData.getType();
     994         171 :                 if ( eType == DOCUMENT )
     995             :                     xRow->appendObject(
     996             :                         rProp,
     997             :                         uno::makeAny(
     998         171 :                             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 = 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         171 :         }
    1033             :     }
    1034             :     else
    1035             :     {
    1036             :         // Append all Core Properties.
    1037             :         xRow->appendString (
    1038             :             beans::Property( OUString("ContentType"),
    1039             :                       -1,
    1040           0 :                       cppu::UnoType<OUString>::get(),
    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 :                       cppu::UnoType<OUString>::get(),
    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 :                       cppu::UnoType<bool>::get(),
    1061             :                       beans::PropertyAttribute::BOUND
    1062             :                         | beans::PropertyAttribute::READONLY ),
    1063           0 :             rData.getIsDocument() );
    1064             :         xRow->appendBoolean(
    1065             :             beans::Property( OUString("IsFolder"),
    1066             :                       -1,
    1067           0 :                       cppu::UnoType<bool>::get(),
    1068             :                       beans::PropertyAttribute::BOUND
    1069             :                         | beans::PropertyAttribute::READONLY ),
    1070           0 :             rData.getIsFolder() );
    1071             :         xRow->appendObject(
    1072             :             beans::Property(
    1073             :                 OUString("CreatableContentsInfo"),
    1074             :                 -1,
    1075           0 :                 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
    1076             :                 beans::PropertyAttribute::BOUND
    1077             :                 | beans::PropertyAttribute::READONLY ),
    1078           0 :             uno::makeAny( rData.getCreatableContentsInfo() ) );
    1079             : 
    1080             :         // Storage is only supported by folders.
    1081           0 :         if ( eType == FOLDER )
    1082             :             xRow->appendObject(
    1083             :                 beans::Property( OUString("Storage"),
    1084             :                           -1,
    1085           0 :                           cppu::UnoType<embed::XStorage>::get(),
    1086             :                           beans::PropertyAttribute::BOUND
    1087             :                             | beans::PropertyAttribute::READONLY ),
    1088           0 :                 uno::makeAny( pProvider->queryStorageClone( rContentId ) ) );
    1089             : 
    1090             :         // DocumentModel is only supported by documents.
    1091           0 :         if ( eType == DOCUMENT )
    1092             :             xRow->appendObject(
    1093             :                 beans::Property( OUString("DocumentModel"),
    1094             :                           -1,
    1095           0 :                           cppu::UnoType<frame::XModel>::get(),
    1096             :                           beans::PropertyAttribute::BOUND
    1097             :                             | beans::PropertyAttribute::READONLY ),
    1098             :                 uno::makeAny(
    1099           0 :                     pProvider->queryDocumentModel( rContentId ) ) );
    1100             : 
    1101             :         // Append all Additional Core Properties.
    1102             : 
    1103             :         uno::Reference< beans::XPropertySet > xSet(
    1104             :             pProvider->getAdditionalPropertySet( rContentId, false ),
    1105           0 :             uno::UNO_QUERY );
    1106           0 :         xRow->appendPropertySet( xSet );
    1107             :     }
    1108             : 
    1109         171 :     return uno::Reference< sdbc::XRow >( xRow.get() );
    1110             : }
    1111             : 
    1112             : 
    1113         171 : uno::Reference< sdbc::XRow > Content::getPropertyValues(
    1114             :                         const uno::Sequence< beans::Property >& rProperties )
    1115             : {
    1116         171 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1117             :     return getPropertyValues( m_xContext,
    1118             :                               rProperties,
    1119             :                               m_aProps,
    1120             :                               m_pProvider,
    1121         171 :                               m_xIdentifier->getContentIdentifier() );
    1122             : }
    1123             : 
    1124             : 
    1125           0 : uno::Sequence< uno::Any > Content::setPropertyValues(
    1126             :         const uno::Sequence< beans::PropertyValue >& rValues,
    1127             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1128             :     throw( uno::Exception )
    1129             : {
    1130           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1131             : 
    1132           0 :     uno::Sequence< uno::Any > aRet( rValues.getLength() );
    1133           0 :     uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
    1134           0 :     sal_Int32 nChanged = 0;
    1135             : 
    1136           0 :     beans::PropertyChangeEvent aEvent;
    1137           0 :     aEvent.Source         = static_cast< cppu::OWeakObject * >( this );
    1138           0 :     aEvent.Further        = sal_False;
    1139             :     //    aEvent.PropertyName   =
    1140           0 :     aEvent.PropertyHandle = -1;
    1141             :     //    aEvent.OldValue       =
    1142             :     //    aEvent.NewValue       =
    1143             : 
    1144           0 :     const beans::PropertyValue* pValues = rValues.getConstArray();
    1145           0 :     sal_Int32 nCount = rValues.getLength();
    1146             : 
    1147           0 :     uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
    1148           0 :     bool bTriedToGetAdditionalPropSet = false;
    1149             : 
    1150           0 :     bool bExchange = false;
    1151           0 :     OUString aOldTitle;
    1152           0 :     sal_Int32 nTitlePos = -1;
    1153             : 
    1154           0 :     for ( sal_Int32 n = 0; n < nCount; ++n )
    1155             :     {
    1156           0 :         const beans::PropertyValue& rValue = pValues[ n ];
    1157             : 
    1158           0 :         if ( rValue.Name == "ContentType" )
    1159             :         {
    1160             :             // Read-only property!
    1161           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1162             :                             OUString( "Property is read-only!" ),
    1163           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1164             :         }
    1165           0 :         else if ( rValue.Name == "IsDocument" )
    1166             :         {
    1167             :             // Read-only property!
    1168           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1169             :                             OUString( "Property is read-only!" ),
    1170           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1171             :         }
    1172           0 :         else if ( rValue.Name == "IsFolder" )
    1173             :         {
    1174             :             // Read-only property!
    1175           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1176             :                             OUString( "Property is read-only!" ),
    1177           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1178             :         }
    1179           0 :         else if ( rValue.Name == "CreatableContentsInfo" )
    1180             :         {
    1181             :             // Read-only property!
    1182           0 :             aRet[ n ] <<= lang::IllegalAccessException(
    1183             :                             OUString( "Property is read-only!" ),
    1184           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1185             :         }
    1186           0 :         else if ( rValue.Name == "Title" )
    1187             :         {
    1188             :             // Title is read-only for root and documents.
    1189           0 :             ContentType eType = m_aProps.getType();
    1190           0 :             if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    1191             :             {
    1192           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1193             :                                 OUString( "Property is read-only!" ),
    1194           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1195             :             }
    1196             :             else
    1197             :             {
    1198           0 :                 OUString aNewValue;
    1199           0 :                 if ( rValue.Value >>= aNewValue )
    1200             :                 {
    1201             :                     // No empty titles!
    1202           0 :                     if ( !aNewValue.isEmpty() )
    1203             :                     {
    1204           0 :                         if ( aNewValue != m_aProps.getTitle() )
    1205             :                         {
    1206             :                             // modified title -> modified URL -> exchange !
    1207           0 :                             if ( m_eState == PERSISTENT )
    1208           0 :                                 bExchange = true;
    1209             : 
    1210           0 :                             aOldTitle = m_aProps.getTitle();
    1211           0 :                             m_aProps.setTitle( aNewValue );
    1212             : 
    1213             :                             // property change event will be sent later...
    1214             : 
    1215             :                             // remember position within sequence of values
    1216             :                             // (for error handling).
    1217           0 :                             nTitlePos = n;
    1218             :                         }
    1219             :                     }
    1220             :                     else
    1221             :                     {
    1222           0 :                         aRet[ n ] <<= lang::IllegalArgumentException(
    1223             :                                     OUString( "Empty Title not allowed!" ),
    1224             :                                     static_cast< cppu::OWeakObject * >( this ),
    1225           0 :                                     -1 );
    1226             :                     }
    1227             :                 }
    1228             :                 else
    1229             :                 {
    1230           0 :                     aRet[ n ] <<= beans::IllegalTypeException(
    1231             :                                 OUString( "Title Property value has wrong type!" ),
    1232           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1233           0 :                 }
    1234             :             }
    1235             :         }
    1236           0 :         else if ( rValue.Name == "Storage" )
    1237             :         {
    1238           0 :             ContentType eType = m_aProps.getType();
    1239           0 :             if ( eType == FOLDER )
    1240             :             {
    1241           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1242             :                                 OUString( "Property is read-only!" ),
    1243           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1244             :             }
    1245             :             else
    1246             :             {
    1247             :                 // Storage is only supported by folders.
    1248           0 :                 aRet[ n ] <<= beans::UnknownPropertyException(
    1249             :                             OUString( "Storage property only supported by folders" ),
    1250           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1251             :             }
    1252             :         }
    1253           0 :         else if ( rValue.Name == "DocumentModel" )
    1254             :         {
    1255           0 :             ContentType eType = m_aProps.getType();
    1256           0 :             if ( eType == DOCUMENT )
    1257             :             {
    1258           0 :                 aRet[ n ] <<= lang::IllegalAccessException(
    1259             :                                 OUString( "Property is read-only!" ),
    1260           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1261             :             }
    1262             :             else
    1263             :             {
    1264             :                 // Storage is only supported by folders.
    1265           0 :                 aRet[ n ] <<= beans::UnknownPropertyException(
    1266             :                             OUString( "DocumentModel property only supported by "
    1267             :                                 "documents" ),
    1268           0 :                             static_cast< cppu::OWeakObject * >( this ) );
    1269             :             }
    1270             :         }
    1271             :         else
    1272             :         {
    1273             :             // Not a Core Property! Maybe it's an Additional Core Property?!
    1274             : 
    1275           0 :             if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
    1276             :             {
    1277           0 :                 xAdditionalPropSet = getAdditionalPropertySet( false );
    1278           0 :                 bTriedToGetAdditionalPropSet = true;
    1279             :             }
    1280             : 
    1281           0 :             if ( xAdditionalPropSet.is() )
    1282             :             {
    1283             :                 try
    1284             :                 {
    1285           0 :                     uno::Any aOldValue = xAdditionalPropSet->getPropertyValue(
    1286           0 :                                                                 rValue.Name );
    1287           0 :                     if ( aOldValue != rValue.Value )
    1288             :                     {
    1289           0 :                         xAdditionalPropSet->setPropertyValue(
    1290           0 :                                                 rValue.Name, rValue.Value );
    1291             : 
    1292           0 :                         aEvent.PropertyName = rValue.Name;
    1293           0 :                         aEvent.OldValue     = aOldValue;
    1294           0 :                         aEvent.NewValue     = rValue.Value;
    1295             : 
    1296           0 :                         aChanges.getArray()[ nChanged ] = aEvent;
    1297           0 :                         nChanged++;
    1298           0 :                     }
    1299             :                 }
    1300           0 :                 catch ( beans::UnknownPropertyException const & e )
    1301             :                 {
    1302           0 :                     aRet[ n ] <<= e;
    1303             :                 }
    1304           0 :                 catch ( lang::WrappedTargetException const & e )
    1305             :                 {
    1306           0 :                     aRet[ n ] <<= e;
    1307             :                 }
    1308           0 :                 catch ( beans::PropertyVetoException const & e )
    1309             :                 {
    1310           0 :                     aRet[ n ] <<= e;
    1311             :                 }
    1312           0 :                 catch ( lang::IllegalArgumentException const & e )
    1313             :                 {
    1314           0 :                     aRet[ n ] <<= e;
    1315             :                 }
    1316             :             }
    1317             :             else
    1318             :             {
    1319           0 :                 aRet[ n ] <<= uno::Exception(
    1320             :                                 OUString( "No property set for storing the value!" ),
    1321           0 :                                 static_cast< cppu::OWeakObject * >( this ) );
    1322             :             }
    1323             :         }
    1324             :     }
    1325             : 
    1326           0 :     if ( bExchange )
    1327             :     {
    1328             :         uno::Reference< ucb::XContentIdentifier > xOldId
    1329           0 :             = m_xIdentifier;
    1330             :         uno::Reference< ucb::XContentIdentifier > xNewId
    1331           0 :             = makeNewIdentifier( m_aProps.getTitle() );
    1332             : 
    1333           0 :         aGuard.clear();
    1334           0 :         if ( exchangeIdentity( xNewId ) )
    1335             :         {
    1336             :             // Adapt persistent data.
    1337           0 :             renameData( xOldId, xNewId );
    1338             : 
    1339             :             // Adapt Additional Core Properties.
    1340           0 :             renameAdditionalPropertySet( xOldId->getContentIdentifier(),
    1341           0 :                                          xNewId->getContentIdentifier(),
    1342           0 :                                          true );
    1343             :         }
    1344             :         else
    1345             :         {
    1346             :             // Roll-back.
    1347           0 :             m_aProps.setTitle( aOldTitle );
    1348           0 :             aOldTitle.clear();
    1349             : 
    1350             :             // Set error .
    1351           0 :             aRet[ nTitlePos ] <<= uno::Exception(
    1352             :                     OUString("Exchange failed!"),
    1353           0 :                     static_cast< cppu::OWeakObject * >( this ) );
    1354           0 :         }
    1355             :     }
    1356             : 
    1357           0 :     if ( !aOldTitle.isEmpty() )
    1358             :     {
    1359           0 :         aEvent.PropertyName = "Title";
    1360           0 :         aEvent.OldValue     = uno::makeAny( aOldTitle );
    1361           0 :         aEvent.NewValue     = uno::makeAny( m_aProps.getTitle() );
    1362             : 
    1363           0 :         aChanges.getArray()[ nChanged ] = aEvent;
    1364           0 :         nChanged++;
    1365             :     }
    1366             : 
    1367           0 :     if ( nChanged > 0 )
    1368             :     {
    1369             :         // Save changes, if content was already made persistent.
    1370           0 :         if ( !bExchange && ( m_eState == PERSISTENT ) )
    1371             :         {
    1372           0 :             if ( !storeData( uno::Reference< io::XInputStream >(), xEnv ) )
    1373             :             {
    1374             :                 uno::Any aProps
    1375             :                     = uno::makeAny(
    1376             :                              beans::PropertyValue(
    1377             :                                  OUString( "Uri"),
    1378             :                                  -1,
    1379           0 :                                  uno::makeAny(m_xIdentifier->
    1380           0 :                                                   getContentIdentifier()),
    1381           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1382             :                 ucbhelper::cancelCommandExecution(
    1383             :                     ucb::IOErrorCode_CANT_WRITE,
    1384             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1385             :                     xEnv,
    1386             :                     OUString( "Cannot store persistent data!" ),
    1387           0 :                     this );
    1388             :                 // Unreachable
    1389             :             }
    1390             :         }
    1391             : 
    1392           0 :         aChanges.realloc( nChanged );
    1393             : 
    1394           0 :         aGuard.clear();
    1395           0 :         notifyPropertiesChange( aChanges );
    1396             :     }
    1397             : 
    1398           0 :     return aRet;
    1399             : }
    1400             : 
    1401             : 
    1402           0 : uno::Any Content::open(
    1403             :                 const ucb::OpenCommandArgument2& rArg,
    1404             :                 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1405             :     throw( uno::Exception )
    1406             : {
    1407           0 :     if ( rArg.Mode == ucb::OpenMode::ALL ||
    1408           0 :          rArg.Mode == ucb::OpenMode::FOLDERS ||
    1409           0 :          rArg.Mode == ucb::OpenMode::DOCUMENTS )
    1410             :     {
    1411             : 
    1412             :         // open command for a folder content
    1413             : 
    1414             : 
    1415             :         uno::Reference< ucb::XDynamicResultSet > xSet
    1416           0 :             = new DynamicResultSet( m_xContext, this, rArg );
    1417           0 :         return uno::makeAny( xSet );
    1418             :     }
    1419             :     else
    1420             :     {
    1421             : 
    1422             :         // open command for a document content
    1423             : 
    1424             : 
    1425           0 :         if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
    1426           0 :              ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
    1427             :         {
    1428             :             // Currently(?) unsupported.
    1429             :             ucbhelper::cancelCommandExecution(
    1430             :                 uno::makeAny( ucb::UnsupportedOpenModeException(
    1431             :                                     OUString(),
    1432             :                                     static_cast< cppu::OWeakObject * >( this ),
    1433             :                                     sal_Int16( rArg.Mode ) ) ),
    1434           0 :                 xEnv );
    1435             :             // Unreachable
    1436             :         }
    1437             : 
    1438           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1439             : 
    1440             :         uno::Reference< io::XActiveDataStreamer > xDataStreamer(
    1441           0 :                                         rArg.Sink, uno::UNO_QUERY );
    1442           0 :         if ( xDataStreamer.is() )
    1443             :         {
    1444             :             // May throw CommandFailedException, DocumentPasswordRequest!
    1445           0 :             uno::Reference< io::XStream > xStream = getStream( xEnv );
    1446           0 :             if ( !xStream.is() )
    1447             :             {
    1448             :                 // No interaction if we are not persistent!
    1449             :                 uno::Any aProps
    1450             :                     = uno::makeAny(
    1451             :                              beans::PropertyValue(
    1452             :                                  OUString( "Uri"),
    1453             :                                  -1,
    1454           0 :                                  uno::makeAny(m_xIdentifier->
    1455           0 :                                                   getContentIdentifier()),
    1456           0 :                                  beans::PropertyState_DIRECT_VALUE));
    1457             :                 ucbhelper::cancelCommandExecution(
    1458             :                     ucb::IOErrorCode_CANT_READ,
    1459             :                     uno::Sequence< uno::Any >(&aProps, 1),
    1460           0 :                     m_eState == PERSISTENT
    1461             :                         ? xEnv
    1462             :                         : uno::Reference< ucb::XCommandEnvironment >(),
    1463             :                     OUString( "Got no data stream!" ),
    1464           0 :                     this );
    1465             :                 // Unreachable
    1466             :             }
    1467             : 
    1468             :             // Done.
    1469           0 :             xDataStreamer->setStream( xStream );
    1470             :         }
    1471             :         else
    1472             :         {
    1473           0 :             uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
    1474           0 :             if ( xOut.is() )
    1475             :             {
    1476             :                 // PUSH: write data into xOut
    1477             : 
    1478             :                 // May throw CommandFailedException, DocumentPasswordRequest!
    1479           0 :                 uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
    1480           0 :                 if ( !xIn.is() )
    1481             :                 {
    1482             :                     // No interaction if we are not persistent!
    1483             :                     uno::Any aProps
    1484             :                         = uno::makeAny(
    1485             :                                  beans::PropertyValue(
    1486             :                                      OUString( "Uri"),
    1487             :                                      -1,
    1488           0 :                                      uno::makeAny(m_xIdentifier->
    1489           0 :                                                       getContentIdentifier()),
    1490           0 :                                      beans::PropertyState_DIRECT_VALUE));
    1491             :                     ucbhelper::cancelCommandExecution(
    1492             :                         ucb::IOErrorCode_CANT_READ,
    1493             :                         uno::Sequence< uno::Any >(&aProps, 1),
    1494           0 :                         m_eState == PERSISTENT
    1495             :                             ? xEnv
    1496             :                             : uno::Reference< ucb::XCommandEnvironment >(),
    1497             :                         OUString("Got no data stream!"),
    1498           0 :                         this );
    1499             :                     // Unreachable
    1500             :                 }
    1501             : 
    1502             :                 try
    1503             :                 {
    1504           0 :                     uno::Sequence< sal_Int8 > aBuffer;
    1505           0 :                     sal_Int32  nRead = xIn->readSomeBytes( aBuffer, 65536 );
    1506             : 
    1507           0 :                     while ( nRead > 0 )
    1508             :                     {
    1509           0 :                         aBuffer.realloc( nRead );
    1510           0 :                         xOut->writeBytes( aBuffer );
    1511           0 :                         aBuffer.realloc( 0 );
    1512           0 :                         nRead = xIn->readSomeBytes( aBuffer, 65536 );
    1513             :                     }
    1514             : 
    1515           0 :                     xOut->closeOutput();
    1516             :                 }
    1517           0 :                 catch ( io::NotConnectedException const & )
    1518             :                 {
    1519             :                     // closeOutput, readSomeBytes, writeBytes
    1520             :                 }
    1521           0 :                 catch ( io::BufferSizeExceededException const & )
    1522             :                 {
    1523             :                     // closeOutput, readSomeBytes, writeBytes
    1524             :                 }
    1525           0 :                 catch ( io::IOException const & )
    1526             :                 {
    1527             :                     // closeOutput, readSomeBytes, writeBytes
    1528           0 :                 }
    1529             :             }
    1530             :             else
    1531             :             {
    1532             :                 uno::Reference< io::XActiveDataSink > xDataSink(
    1533           0 :                                                 rArg.Sink, uno::UNO_QUERY );
    1534           0 :                 if ( xDataSink.is() )
    1535             :                 {
    1536             :                     // PULL: wait for client read
    1537             : 
    1538             :                     // May throw CommandFailedException, DocumentPasswordRequest!
    1539           0 :                     uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
    1540           0 :                     if ( !xIn.is() )
    1541             :                     {
    1542             :                         // No interaction if we are not persistent!
    1543             :                         uno::Any aProps
    1544             :                             = uno::makeAny(
    1545             :                                      beans::PropertyValue(
    1546             :                                          OUString( "Uri"),
    1547             :                                          -1,
    1548           0 :                                          uno::makeAny(m_xIdentifier->
    1549           0 :                                                           getContentIdentifier()),
    1550           0 :                                          beans::PropertyState_DIRECT_VALUE));
    1551             :                         ucbhelper::cancelCommandExecution(
    1552             :                             ucb::IOErrorCode_CANT_READ,
    1553             :                             uno::Sequence< uno::Any >(&aProps, 1),
    1554           0 :                             m_eState == PERSISTENT
    1555             :                                 ? xEnv
    1556             :                                 : uno::Reference<
    1557             :                                       ucb::XCommandEnvironment >(),
    1558             :                             OUString( "Got no data stream!" ),
    1559           0 :                             this );
    1560             :                         // Unreachable
    1561             :                     }
    1562             : 
    1563             :                     // Done.
    1564           0 :                     xDataSink->setInputStream( xIn );
    1565             :                 }
    1566             :                 else
    1567             :                 {
    1568             :                     ucbhelper::cancelCommandExecution(
    1569             :                         uno::makeAny(
    1570             :                             ucb::UnsupportedDataSinkException(
    1571             :                                     OUString(),
    1572             :                                     static_cast< cppu::OWeakObject * >( this ),
    1573             :                                     rArg.Sink ) ),
    1574           0 :                         xEnv );
    1575             :                     // Unreachable
    1576           0 :                 }
    1577           0 :             }
    1578           0 :         }
    1579             :     }
    1580             : 
    1581           0 :     return uno::Any();
    1582             : }
    1583             : 
    1584             : 
    1585           0 : void Content::insert( const uno::Reference< io::XInputStream >& xData,
    1586             :                       sal_Int32 nNameClashResolve,
    1587             :                       const uno::Reference<
    1588             :                           ucb::XCommandEnvironment > & xEnv )
    1589             :     throw( uno::Exception )
    1590             : {
    1591           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1592             : 
    1593           0 :     ContentType eType = m_aProps.getType();
    1594             : 
    1595             :     OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
    1596             :                 "insert command only supported by streams and folders!" );
    1597             : 
    1598           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    1599             : 
    1600             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    1601             : #if OSL_DEBUG_LEVEL > 0
    1602             :     if ( eType == STREAM )
    1603             :     {
    1604             :         Uri aParentUri( aUri.getParentUri() );
    1605             :         OSL_ENSURE( !aParentUri.isDocument(),
    1606             :                     "insert command not supported by streams that are direct "
    1607             :                     "children of document root!" );
    1608             :     }
    1609             : #endif
    1610             : #endif
    1611             : 
    1612             :     // Check, if all required properties were set.
    1613           0 :     if ( eType == FOLDER )
    1614             :     {
    1615             :         // Required: Title
    1616             : 
    1617           0 :         if ( m_aProps.getTitle().isEmpty() )
    1618           0 :             m_aProps.setTitle( aUri.getDecodedName() );
    1619             :     }
    1620             :     else // stream
    1621             :     {
    1622             :         // Required: data
    1623             : 
    1624           0 :         if ( !xData.is() )
    1625             :         {
    1626             :             ucbhelper::cancelCommandExecution(
    1627             :                 uno::makeAny( ucb::MissingInputStreamException(
    1628             :                                 OUString(),
    1629             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1630           0 :                 xEnv );
    1631             :             // Unreachable
    1632             :         }
    1633             : 
    1634             :         // Required: Title
    1635             : 
    1636           0 :         if ( m_aProps.getTitle().isEmpty() )
    1637           0 :             m_aProps.setTitle( aUri.getDecodedName() );
    1638             :     }
    1639             : 
    1640           0 :     OUStringBuffer aNewURL = aUri.getParentUri();
    1641           0 :     aNewURL.append( m_aProps.getTitle() );
    1642           0 :     Uri aNewUri( aNewURL.makeStringAndClear() );
    1643             : 
    1644             :     // Handle possible name clash...
    1645           0 :     switch ( nNameClashResolve )
    1646             :     {
    1647             :         // fail.
    1648             :         case ucb::NameClash::ERROR:
    1649           0 :             if ( hasData( aNewUri ) )
    1650             :             {
    1651             :                 ucbhelper::cancelCommandExecution(
    1652             :                     uno::makeAny( ucb::NameClashException(
    1653             :                                     OUString(),
    1654             :                                     static_cast< cppu::OWeakObject * >( this ),
    1655             :                                     task::InteractionClassification_ERROR,
    1656           0 :                                     m_aProps.getTitle() ) ),
    1657           0 :                     xEnv );
    1658             :                 // Unreachable
    1659             :             }
    1660           0 :             break;
    1661             : 
    1662             :         // replace (possibly) existing object.
    1663             :         case ucb::NameClash::OVERWRITE:
    1664           0 :             break;
    1665             : 
    1666             :         // "invent" a new valid title.
    1667             :         case ucb::NameClash::RENAME:
    1668           0 :             if ( hasData( aNewUri ) )
    1669             :             {
    1670           0 :                 sal_Int32 nTry = 0;
    1671             : 
    1672           0 :                 do
    1673             :                 {
    1674           0 :                     OUStringBuffer aNew = aNewUri.getUri();
    1675           0 :                     aNew.appendAscii( "_" );
    1676           0 :                     aNew.append( OUString::number( ++nTry ) );
    1677           0 :                     aNewUri.setUri( aNew.makeStringAndClear() );
    1678             :                 }
    1679           0 :                 while ( hasData( aNewUri ) && ( nTry < 1000 ) );
    1680             : 
    1681           0 :                 if ( nTry == 1000 )
    1682             :                 {
    1683             :                     ucbhelper::cancelCommandExecution(
    1684             :                         uno::makeAny(
    1685             :                             ucb::UnsupportedNameClashException(
    1686             :                                 OUString( "Unable to resolve name clash!" ),
    1687             :                                 static_cast< cppu::OWeakObject * >( this ),
    1688             :                                 nNameClashResolve ) ),
    1689           0 :                         xEnv );
    1690             :                     // Unreachable
    1691             :                 }
    1692             :                 else
    1693             :                 {
    1694           0 :                     OUStringBuffer aNewTitle = m_aProps.getTitle();
    1695           0 :                     aNewTitle.appendAscii( "_" );
    1696           0 :                     aNewTitle.append( OUString::number( ++nTry ) );
    1697           0 :                     m_aProps.setTitle( aNewTitle.makeStringAndClear() );
    1698             :                 }
    1699             :             }
    1700           0 :             break;
    1701             : 
    1702             :         case ucb::NameClash::KEEP: // deprecated
    1703             :         case ucb::NameClash::ASK:
    1704             :         default:
    1705           0 :             if ( hasData( aNewUri ) )
    1706             :             {
    1707             :                 ucbhelper::cancelCommandExecution(
    1708             :                     uno::makeAny(
    1709             :                         ucb::UnsupportedNameClashException(
    1710             :                             OUString(),
    1711             :                             static_cast< cppu::OWeakObject * >( this ),
    1712             :                             nNameClashResolve ) ),
    1713           0 :                     xEnv );
    1714             :                 // Unreachable
    1715             :             }
    1716           0 :             break;
    1717             :     }
    1718             : 
    1719             :     // Identifier changed?
    1720           0 :     bool bNewId = ( aUri != aNewUri );
    1721             : 
    1722           0 :     if ( bNewId )
    1723             :     {
    1724             :         m_xIdentifier
    1725           0 :             = new ::ucbhelper::ContentIdentifier( aNewUri.getUri() );
    1726             :     }
    1727             : 
    1728           0 :     if ( !storeData( xData, xEnv ) )
    1729             :     {
    1730             :         uno::Any aProps
    1731             :             = uno::makeAny(beans::PropertyValue(
    1732             :                                   OUString( "Uri"),
    1733             :                                   -1,
    1734           0 :                                   uno::makeAny(m_xIdentifier->
    1735           0 :                                                    getContentIdentifier()),
    1736           0 :                                   beans::PropertyState_DIRECT_VALUE));
    1737             :         ucbhelper::cancelCommandExecution(
    1738             :             ucb::IOErrorCode_CANT_WRITE,
    1739             :             uno::Sequence< uno::Any >(&aProps, 1),
    1740             :             xEnv,
    1741             :             OUString("Cannot store persistent data!"),
    1742           0 :             this );
    1743             :         // Unreachable
    1744             :     }
    1745             : 
    1746           0 :     m_eState = PERSISTENT;
    1747             : 
    1748           0 :     if ( bNewId )
    1749             :     {
    1750             :         //loadData( m_pProvider, m_aUri, m_aProps );
    1751             : 
    1752           0 :         aGuard.clear();
    1753           0 :         inserted();
    1754           0 :     }
    1755           0 : }
    1756             : 
    1757             : 
    1758           0 : void Content::destroy( bool bDeletePhysical,
    1759             :                        const uno::Reference<
    1760             :                            ucb::XCommandEnvironment > & xEnv )
    1761             :     throw( uno::Exception )
    1762             : {
    1763             :     // @@@ take care about bDeletePhysical -> trashcan support
    1764             : 
    1765           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1766             : 
    1767           0 :     ContentType eType = m_aProps.getType();
    1768             : 
    1769             :     OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
    1770             :                 "delete command only supported by streams and folders!" );
    1771             : 
    1772           0 :     uno::Reference< ucb::XContent > xThis = this;
    1773             : 
    1774             :     // Persistent?
    1775           0 :     if ( m_eState != PERSISTENT )
    1776             :     {
    1777             :         ucbhelper::cancelCommandExecution(
    1778             :             uno::makeAny( ucb::UnsupportedCommandException(
    1779             :                                 OUString( "Not persistent!" ),
    1780             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1781           0 :             xEnv );
    1782             :         // Unreachable
    1783             :     }
    1784             : 
    1785           0 :     m_eState = DEAD;
    1786             : 
    1787           0 :     aGuard.clear();
    1788           0 :     deleted();
    1789             : 
    1790           0 :     if ( eType == FOLDER )
    1791             :     {
    1792             :         // Process instantiated children...
    1793             : 
    1794           0 :         ContentRefList aChildren;
    1795           0 :         queryChildren( aChildren );
    1796             : 
    1797           0 :         ContentRefList::const_iterator it  = aChildren.begin();
    1798           0 :         ContentRefList::const_iterator end = aChildren.end();
    1799             : 
    1800           0 :         while ( it != end )
    1801             :         {
    1802           0 :             (*it)->destroy( bDeletePhysical, xEnv );
    1803           0 :             ++it;
    1804           0 :         }
    1805           0 :     }
    1806           0 : }
    1807             : 
    1808             : 
    1809           0 : void Content::notifyDocumentClosed()
    1810             : {
    1811           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1812             : 
    1813           0 :     m_eState = DEAD;
    1814             : 
    1815             :     // @@@ anything else to reset or such?
    1816             : 
    1817             :     // callback follows!
    1818           0 :     aGuard.clear();
    1819             : 
    1820             :     // Propagate destruction to content event listeners
    1821             :     // Remove this from provider's content list.
    1822           0 :     deleted();
    1823           0 : }
    1824             : 
    1825             : 
    1826             : uno::Reference< ucb::XContent >
    1827           0 : Content::queryChildContent( const OUString & rRelativeChildUri )
    1828             : {
    1829           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    1830             : 
    1831           0 :     const OUString aMyId = getIdentifier()->getContentIdentifier();
    1832           0 :     OUStringBuffer aBuf( aMyId );
    1833           0 :     if ( !aMyId.endsWith("/") )
    1834           0 :         aBuf.appendAscii( "/" );
    1835           0 :     if ( !rRelativeChildUri.startsWith("/") )
    1836           0 :         aBuf.append( rRelativeChildUri );
    1837             :     else
    1838           0 :         aBuf.append( rRelativeChildUri.copy( 1 ) );
    1839             : 
    1840             :     uno::Reference< ucb::XContentIdentifier > xChildId
    1841           0 :         = new ::ucbhelper::ContentIdentifier( aBuf.makeStringAndClear() );
    1842             : 
    1843           0 :     uno::Reference< ucb::XContent > xChild;
    1844             :     try
    1845             :     {
    1846           0 :         xChild = m_pProvider->queryContent( xChildId );
    1847             :     }
    1848           0 :     catch ( ucb::IllegalIdentifierException const & )
    1849             :     {
    1850             :         // handled below.
    1851             :     }
    1852             : 
    1853             :     OSL_ENSURE( xChild.is(),
    1854             :                 "Content::queryChildContent - unable to create child content!" );
    1855           0 :     return xChild;
    1856             : }
    1857             : 
    1858             : 
    1859           0 : void Content::notifyChildRemoved( const OUString & rRelativeChildUri )
    1860             : {
    1861           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1862             : 
    1863             :     // Ugly! Need to create child content object, just to fill event properly.
    1864             :     uno::Reference< ucb::XContent > xChild
    1865           0 :         = queryChildContent( rRelativeChildUri );
    1866             : 
    1867           0 :     if ( xChild.is() )
    1868             :     {
    1869             :         // callback follows!
    1870           0 :         aGuard.clear();
    1871             : 
    1872             :         // Notify "REMOVED" event.
    1873             :         ucb::ContentEvent aEvt(
    1874             :             static_cast< cppu::OWeakObject * >( this ),
    1875             :             ucb::ContentAction::REMOVED,
    1876             :             xChild,
    1877           0 :             getIdentifier() );
    1878           0 :         notifyContentEvent( aEvt );
    1879           0 :     }
    1880           0 : }
    1881             : 
    1882             : 
    1883           0 : void Content::notifyChildInserted( const OUString & rRelativeChildUri )
    1884             : {
    1885           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1886             : 
    1887             :     // Ugly! Need to create child content object, just to fill event properly.
    1888             :     uno::Reference< ucb::XContent > xChild
    1889           0 :         = queryChildContent( rRelativeChildUri );
    1890             : 
    1891           0 :     if ( xChild.is() )
    1892             :     {
    1893             :         // callback follows!
    1894           0 :         aGuard.clear();
    1895             : 
    1896             :         // Notify "INSERTED" event.
    1897             :         ucb::ContentEvent aEvt(
    1898             :             static_cast< cppu::OWeakObject * >( this ),
    1899             :             ucb::ContentAction::INSERTED,
    1900             :             xChild,
    1901           0 :             getIdentifier() );
    1902           0 :         notifyContentEvent( aEvt );
    1903           0 :     }
    1904           0 : }
    1905             : 
    1906             : 
    1907           0 : void Content::transfer(
    1908             :             const ucb::TransferInfo& rInfo,
    1909             :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1910             :     throw( uno::Exception )
    1911             : {
    1912           0 :     osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
    1913             : 
    1914             :     // Persistent?
    1915           0 :     if ( m_eState != PERSISTENT )
    1916             :     {
    1917             :         ucbhelper::cancelCommandExecution(
    1918             :             uno::makeAny( ucb::UnsupportedCommandException(
    1919             :                                 OUString( "Not persistent!" ),
    1920             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
    1921           0 :             xEnv );
    1922             :         // Unreachable
    1923             :     }
    1924             : 
    1925             :     // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
    1926             : 
    1927           0 :     if ( ( rInfo.SourceURL.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
    1928             :     {
    1929             :         // Invalid length (to short).
    1930             :         ucbhelper::cancelCommandExecution(
    1931             :             uno::makeAny( ucb::InteractiveBadTransferURLException(
    1932             :                             OUString(),
    1933             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
    1934           0 :             xEnv );
    1935             :         // Unreachable
    1936             :     }
    1937             : 
    1938             :     OUString aScheme
    1939             :         = rInfo.SourceURL.copy( 0, TDOC_URL_SCHEME_LENGTH + 2 )
    1940           0 :             .toAsciiLowerCase();
    1941           0 :     if ( aScheme != TDOC_URL_SCHEME ":/" )
    1942             :     {
    1943             :         // Invalid scheme.
    1944             :         ucbhelper::cancelCommandExecution(
    1945             :             uno::makeAny( ucb::InteractiveBadTransferURLException(
    1946             :                             OUString(),
    1947             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
    1948           0 :             xEnv );
    1949             :         // Unreachable
    1950             :     }
    1951             : 
    1952             :     // Does source URI describe a tdoc folder or stream?
    1953           0 :     Uri aSourceUri( rInfo.SourceURL );
    1954           0 :     if ( !aSourceUri.isValid() )
    1955             :     {
    1956             :         ucbhelper::cancelCommandExecution(
    1957             :             uno::makeAny( lang::IllegalArgumentException(
    1958             :                                 OUString( "Invalid source URI! Syntax!" ),
    1959             :                                 static_cast< cppu::OWeakObject * >( this ),
    1960             :                                 -1 ) ),
    1961           0 :             xEnv );
    1962             :         // Unreachable
    1963             :     }
    1964             : 
    1965           0 :     if ( aSourceUri.isRoot() || aSourceUri.isDocument() )
    1966             :     {
    1967             :         ucbhelper::cancelCommandExecution(
    1968             :             uno::makeAny( lang::IllegalArgumentException(
    1969             :                                 OUString( "Invalid source URI! "
    1970             :                                     "Must describe a folder or stream!" ),
    1971             :                                 static_cast< cppu::OWeakObject * >( this ),
    1972             :                                 -1 ) ),
    1973           0 :             xEnv );
    1974             :         // Unreachable
    1975             :     }
    1976             : 
    1977             :     // Is source not a parent of me / not me?
    1978           0 :     OUString aId = m_xIdentifier->getContentIdentifier();
    1979           0 :     sal_Int32 nPos = aId.lastIndexOf( '/' );
    1980           0 :     if ( nPos != ( aId.getLength() - 1 ) )
    1981             :     {
    1982             :         // No trailing slash found. Append.
    1983           0 :         aId += "/";
    1984             :     }
    1985             : 
    1986           0 :     if ( rInfo.SourceURL.getLength() <= aId.getLength() )
    1987             :     {
    1988           0 :         if ( aId.startsWith( rInfo.SourceURL ) )
    1989             :         {
    1990             :             uno::Any aProps
    1991             :                 = uno::makeAny(beans::PropertyValue(
    1992             :                                       OUString( "Uri"),
    1993             :                                       -1,
    1994             :                                       uno::makeAny( rInfo.SourceURL ),
    1995           0 :                                       beans::PropertyState_DIRECT_VALUE));
    1996             :             ucbhelper::cancelCommandExecution(
    1997             :                 ucb::IOErrorCode_RECURSIVE,
    1998             :                 uno::Sequence< uno::Any >(&aProps, 1),
    1999             :                 xEnv,
    2000             :                 OUString( "Target is equal to or is a child of source!" ),
    2001           0 :                 this );
    2002             :             // Unreachable
    2003             :         }
    2004             :     }
    2005             : 
    2006             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2007           0 :     if ( m_aProps.getType() == DOCUMENT )
    2008             :     {
    2009           0 :         bool bOK = false;
    2010             : 
    2011             :         uno::Reference< embed::XStorage > xStorage
    2012             :             = m_pProvider->queryStorage(
    2013           0 :                 aSourceUri.getParentUri(), READ_WRITE_NOCREATE );
    2014           0 :         if ( xStorage.is() )
    2015             :         {
    2016             :             try
    2017             :             {
    2018           0 :                 if ( xStorage->isStreamElement( aSourceUri.getDecodedName() ) )
    2019             :                 {
    2020             :                     ucbhelper::cancelCommandExecution(
    2021             :                         uno::makeAny( lang::IllegalArgumentException(
    2022             :                                         OUString( "Invalid source URI! "
    2023             :                                             "Streams cannot be created as "
    2024             :                                             "children of document root!" ),
    2025             :                                         static_cast< cppu::OWeakObject * >(
    2026             :                                             this ),
    2027             :                                         -1 ) ),
    2028           0 :                         xEnv );
    2029             :                     // Unreachable
    2030             :                 }
    2031           0 :                 bOK = true;
    2032             :             }
    2033           0 :             catch ( container::NoSuchElementException const & )
    2034             :             {
    2035             :                 // handled below.
    2036             :             }
    2037           0 :             catch ( lang::IllegalArgumentException const & )
    2038             :             {
    2039             :                 // handled below.
    2040             :             }
    2041           0 :             catch ( embed::InvalidStorageException const & )
    2042             :             {
    2043             :                 // handled below.
    2044             :             }
    2045             :         }
    2046             : 
    2047           0 :         if ( !bOK )
    2048             :         {
    2049             :             ucbhelper::cancelCommandExecution(
    2050             :                 uno::makeAny( lang::IllegalArgumentException(
    2051             :                                     OUString( "Invalid source URI! "
    2052             :                                         "Unabale to determine source type!" ),
    2053             :                                     static_cast< cppu::OWeakObject * >( this ),
    2054             :                                     -1 ) ),
    2055           0 :                 xEnv );
    2056             :             // Unreachable
    2057           0 :         }
    2058             :     }
    2059             : #endif
    2060             : 
    2061             : 
    2062             :     // Copy data.
    2063             : 
    2064             : 
    2065           0 :     OUString aNewName( !rInfo.NewTitle.isEmpty()
    2066             :                                 ? rInfo.NewTitle
    2067           0 :                                 : aSourceUri.getDecodedName() );
    2068             : 
    2069           0 :     if ( !copyData( aSourceUri, aNewName ) )
    2070             :     {
    2071             :         uno::Any aProps
    2072             :             = uno::makeAny(
    2073             :                      beans::PropertyValue(
    2074             :                          OUString( "Uri"),
    2075             :                          -1,
    2076             :                          uno::makeAny( rInfo.SourceURL ),
    2077           0 :                          beans::PropertyState_DIRECT_VALUE));
    2078             :         ucbhelper::cancelCommandExecution(
    2079             :             ucb::IOErrorCode_CANT_WRITE,
    2080             :             uno::Sequence< uno::Any >(&aProps, 1),
    2081             :             xEnv,
    2082             :             OUString( "Cannot copy data!"  ),
    2083           0 :             this );
    2084             :         // Unreachable
    2085             :     }
    2086             : 
    2087             : 
    2088             :     // Copy own and all children's Additional Core Properties.
    2089             : 
    2090             : 
    2091           0 :     OUString aTargetUri = m_xIdentifier->getContentIdentifier();
    2092           0 :     if ( ( aTargetUri.lastIndexOf( '/' ) + 1 ) != aTargetUri.getLength() )
    2093           0 :         aTargetUri += "/";
    2094             : 
    2095           0 :     if ( !rInfo.NewTitle.isEmpty() )
    2096           0 :         aTargetUri += ::ucb_impl::urihelper::encodeSegment( rInfo.NewTitle );
    2097             :     else
    2098           0 :         aTargetUri += aSourceUri.getName();
    2099             : 
    2100           0 :     if ( !copyAdditionalPropertySet(
    2101           0 :             aSourceUri.getUri(), aTargetUri, true ) )
    2102             :     {
    2103             :         uno::Any aProps
    2104             :             = uno::makeAny(
    2105             :                      beans::PropertyValue(
    2106             :                          OUString( "Uri"),
    2107             :                          -1,
    2108             :                          uno::makeAny( rInfo.SourceURL ),
    2109           0 :                          beans::PropertyState_DIRECT_VALUE));
    2110             :         ucbhelper::cancelCommandExecution(
    2111             :             ucb::IOErrorCode_CANT_WRITE,
    2112             :             uno::Sequence< uno::Any >(&aProps, 1),
    2113             :             xEnv,
    2114             :             OUString( "Cannot copy additional properties!"  ),
    2115           0 :             this );
    2116             :         // Unreachable
    2117             :     }
    2118             : 
    2119             : 
    2120             :     // Propagate new content.
    2121             : 
    2122             : 
    2123           0 :     rtl::Reference< Content > xTarget;
    2124             :     try
    2125             :     {
    2126             :         uno::Reference< ucb::XContentIdentifier > xTargetId
    2127           0 :             = new ::ucbhelper::ContentIdentifier( aTargetUri );
    2128             : 
    2129             :         // Note: The static cast is okay here, because its sure that
    2130             :         //       m_xProvider is always the WebDAVContentProvider.
    2131           0 :         xTarget = static_cast< Content * >(
    2132           0 :             m_pProvider->queryContent( xTargetId ).get() );
    2133             : 
    2134             :     }
    2135           0 :     catch ( ucb::IllegalIdentifierException const & )
    2136             :     {
    2137             :         // queryContent
    2138             :     }
    2139             : 
    2140           0 :     if ( !xTarget.is() )
    2141             :     {
    2142             :         uno::Any aProps
    2143             :             = uno::makeAny(beans::PropertyValue(
    2144             :                                   OUString( "Uri"),
    2145             :                                   -1,
    2146             :                                   uno::makeAny( aTargetUri ),
    2147           0 :                                   beans::PropertyState_DIRECT_VALUE));
    2148             :         ucbhelper::cancelCommandExecution(
    2149             :             ucb::IOErrorCode_CANT_READ,
    2150             :             uno::Sequence< uno::Any >(&aProps, 1),
    2151             :             xEnv,
    2152             :             OUString( "Cannot instanciate target object!" ),
    2153           0 :             this );
    2154             :         // Unreachable
    2155             :     }
    2156             : 
    2157             :     // Announce transferred content in its new folder.
    2158           0 :     xTarget->inserted();
    2159             : 
    2160             : 
    2161             :     // Remove source, if requested
    2162             : 
    2163             : 
    2164           0 :     if ( rInfo.MoveData )
    2165             :     {
    2166           0 :         rtl::Reference< Content > xSource;
    2167             :         try
    2168             :         {
    2169             :             uno::Reference< ucb::XContentIdentifier >
    2170           0 :                 xSourceId = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
    2171             : 
    2172             :             // Note: The static cast is okay here, because its sure
    2173             :             //       that m_xProvider is always the ContentProvider.
    2174           0 :             xSource = static_cast< Content * >(
    2175           0 :                 m_xProvider->queryContent( xSourceId ).get() );
    2176             :         }
    2177           0 :         catch ( ucb::IllegalIdentifierException const & )
    2178             :         {
    2179             :             // queryContent
    2180             :         }
    2181             : 
    2182           0 :         if ( !xSource.is() )
    2183             :         {
    2184             :             uno::Any aProps
    2185             :                 = uno::makeAny(beans::PropertyValue(
    2186             :                                       OUString( "Uri"),
    2187             :                                       -1,
    2188             :                                       uno::makeAny( rInfo.SourceURL ),
    2189           0 :                                       beans::PropertyState_DIRECT_VALUE));
    2190             :             ucbhelper::cancelCommandExecution(
    2191             :                 ucb::IOErrorCode_CANT_READ,
    2192             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2193             :                 xEnv,
    2194             :                 OUString( "Cannot instanciate target object!" ),
    2195           0 :                 this );
    2196             :             // Unreachable
    2197             :         }
    2198             : 
    2199             :         // Propagate destruction (recursively).
    2200           0 :         xSource->destroy( true, xEnv );
    2201             : 
    2202             :         // Remove all persistent data of source and its children.
    2203           0 :         if ( !xSource->removeData() )
    2204             :         {
    2205             :             uno::Any aProps
    2206             :                 = uno::makeAny(
    2207             :                          beans::PropertyValue(
    2208             :                              OUString( "Uri"),
    2209             :                              -1,
    2210             :                              uno::makeAny( rInfo.SourceURL ),
    2211           0 :                              beans::PropertyState_DIRECT_VALUE));
    2212             :             ucbhelper::cancelCommandExecution(
    2213             :                 ucb::IOErrorCode_CANT_WRITE,
    2214             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2215             :                 xEnv,
    2216             :                 OUString( "Cannot remove persistent data of source object!" ),
    2217           0 :                 this );
    2218             :             // Unreachable
    2219             :         }
    2220             : 
    2221             :         // Remove own and all children's Additional Core Properties.
    2222           0 :         if ( !xSource->removeAdditionalPropertySet( true ) )
    2223             :         {
    2224             :             uno::Any aProps
    2225             :                 = uno::makeAny(
    2226             :                          beans::PropertyValue(
    2227             :                              OUString( "Uri"),
    2228             :                              -1,
    2229             :                              uno::makeAny( rInfo.SourceURL ),
    2230           0 :                              beans::PropertyState_DIRECT_VALUE));
    2231             :             ucbhelper::cancelCommandExecution(
    2232             :                 ucb::IOErrorCode_CANT_WRITE,
    2233             :                 uno::Sequence< uno::Any >(&aProps, 1),
    2234             :                 xEnv,
    2235             :                 OUString( "Cannot remove additional properties of source object!" ),
    2236           0 :                 this );
    2237             :             // Unreachable
    2238           0 :         }
    2239             : 
    2240           0 :     } // rInfo.MoveData
    2241           0 : }
    2242             : 
    2243             : 
    2244             : //static
    2245           0 : bool Content::hasData( ContentProvider* pProvider, const Uri & rUri )
    2246             : {
    2247           0 :     if ( rUri.isRoot() )
    2248             :     {
    2249           0 :         return true; // root has no storage
    2250             :     }
    2251           0 :     else if ( rUri.isDocument() )
    2252             :     {
    2253             :         uno::Reference< embed::XStorage > xStorage
    2254           0 :             = pProvider->queryStorage( rUri.getUri(), READ );
    2255           0 :         return xStorage.is();
    2256             :     }
    2257             :     else
    2258             :     {
    2259             :         // folder or stream
    2260             : 
    2261             :         // Ask parent storage. In case that rUri describes a stream,
    2262             :         // ContentProvider::queryStorage( rUri ) would return null.
    2263             : 
    2264             :         uno::Reference< embed::XStorage > xStorage
    2265           0 :             = pProvider->queryStorage( rUri.getParentUri(), READ );
    2266             : 
    2267           0 :         if ( !xStorage.is() )
    2268           0 :             return false;
    2269             : 
    2270             :         uno::Reference< container::XNameAccess > xParentNA(
    2271           0 :             xStorage, uno::UNO_QUERY );
    2272             : 
    2273             :         OSL_ENSURE( xParentNA.is(), "Got no css.container.XNameAccess!" );
    2274             : 
    2275           0 :         return xParentNA->hasByName( rUri.getDecodedName() );
    2276             :     }
    2277             : }
    2278             : 
    2279             : 
    2280             : //static
    2281         328 : bool Content::loadData( ContentProvider* pProvider,
    2282             :                         const Uri & rUri,
    2283             :                         ContentProperties& rProps )
    2284             : {
    2285         328 :     if ( rUri.isRoot() ) // root has no storage, but can always be created
    2286             :     {
    2287             :         rProps
    2288           0 :             = ContentProperties(
    2289           0 :                 ROOT, pProvider->queryStorageTitle( rUri.getUri() ) );
    2290             :     }
    2291         328 :     else if ( rUri.isDocument() ) // document must have storage
    2292             :     {
    2293             :         uno::Reference< embed::XStorage > xStorage
    2294         328 :             = pProvider->queryStorage( rUri.getUri(), READ );
    2295             : 
    2296         328 :         if ( !xStorage.is() )
    2297           0 :             return false;
    2298             : 
    2299             :         rProps
    2300         656 :             = ContentProperties(
    2301         984 :                 DOCUMENT, pProvider->queryStorageTitle( rUri.getUri() ) );
    2302             :     }
    2303             :     else // stream or folder; stream has no storage; folder has storage
    2304             :     {
    2305             :         uno::Reference< embed::XStorage > xStorage
    2306           0 :             = pProvider->queryStorage( rUri.getParentUri(), READ );
    2307             : 
    2308           0 :         if ( !xStorage.is() )
    2309           0 :             return false;
    2310             : 
    2311             :         // Check whether exists at all, is stream or folder
    2312             :         try
    2313             :         {
    2314             :             // return: true  -> folder
    2315             :             // return: false -> stream
    2316             :             // NoSuchElementException -> neither folder nor stream
    2317             :             bool bIsFolder
    2318           0 :                 = xStorage->isStorageElement( rUri.getDecodedName() );
    2319             : 
    2320             :             rProps
    2321           0 :                 = ContentProperties(
    2322             :                     bIsFolder ? FOLDER : STREAM,
    2323           0 :                     pProvider->queryStorageTitle( rUri.getUri() ) );
    2324             :         }
    2325           0 :         catch ( container::NoSuchElementException const & )
    2326             :         {
    2327             :             // there is no element with such name
    2328             :             //OSL_ENSURE( false, "Caught NoSuchElementException!" );
    2329           0 :             return false;
    2330             :         }
    2331           0 :         catch ( lang::IllegalArgumentException const & )
    2332             :         {
    2333             :             // an illegal argument is provided
    2334             :             OSL_FAIL( "Caught IllegalArgumentException!" );
    2335           0 :             return false;
    2336             :         }
    2337           0 :         catch ( embed::InvalidStorageException const & )
    2338             :         {
    2339             :             // this storage is in invalid state for any reason
    2340             :             OSL_FAIL( "Caught InvalidStorageException!" );
    2341           0 :             return false;
    2342           0 :         }
    2343             :     }
    2344         328 :     return true;
    2345             : }
    2346             : 
    2347             : 
    2348           0 : bool Content::storeData( const uno::Reference< io::XInputStream >& xData,
    2349             :                          const uno::Reference<
    2350             :                             ucb::XCommandEnvironment >& xEnv )
    2351             :     throw ( ucb::CommandFailedException,
    2352             :             task::DocumentPasswordRequest,
    2353             :             css::uno::RuntimeException )
    2354             : {
    2355           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2356             : 
    2357           0 :     ContentType eType = m_aProps.getType();
    2358           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2359             :     {
    2360             :         OSL_FAIL( "storeData not supported by root and documents!" );
    2361           0 :         return false;
    2362             :     }
    2363             : 
    2364           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    2365             : 
    2366           0 :     if ( eType == FOLDER )
    2367             :     {
    2368             :         uno::Reference< embed::XStorage > xStorage
    2369           0 :             = m_pProvider->queryStorage( aUri.getUri(), READ_WRITE_CREATE );
    2370             : 
    2371           0 :         if ( !xStorage.is() )
    2372           0 :             return false;
    2373             : 
    2374             :         uno::Reference< beans::XPropertySet > xPropSet(
    2375           0 :             xStorage, uno::UNO_QUERY );
    2376             :         OSL_ENSURE( xPropSet.is(),
    2377             :                     "Content::storeData - Got no XPropertySet interface!" );
    2378           0 :         if ( !xPropSet.is() )
    2379           0 :             return false;
    2380             : 
    2381             :         try
    2382             :         {
    2383             :             // According to MBA, if no mediatype is set, folder and all
    2384             :             // its contents will be lost on save of the document!!!
    2385           0 :             xPropSet->setPropertyValue(
    2386             :                 OUString(  "MediaType"  ),
    2387             :                 uno::makeAny(
    2388             :                     OUString(                        // @@@ better mediatype
    2389           0 :                         "application/binary"  ) ) );
    2390             :         }
    2391           0 :         catch ( beans::UnknownPropertyException const & )
    2392             :         {
    2393             :             OSL_FAIL( "Property MediaType not supported!" );
    2394           0 :             return false;
    2395             :         }
    2396           0 :         catch ( beans::PropertyVetoException const & )
    2397             :         {
    2398             :             OSL_FAIL( "Caught PropertyVetoException!" );
    2399           0 :             return false;
    2400             :         }
    2401           0 :         catch ( lang::IllegalArgumentException const & )
    2402             :         {
    2403             :             OSL_FAIL( "Caught IllegalArgumentException!" );
    2404           0 :             return false;
    2405             :         }
    2406           0 :         catch ( lang::WrappedTargetException const & )
    2407             :         {
    2408             :             OSL_FAIL( "Caught WrappedTargetException!" );
    2409           0 :             return false;
    2410             :         }
    2411             : 
    2412           0 :         if ( !commitStorage( xStorage ) )
    2413           0 :             return false;
    2414             :     }
    2415           0 :     else if ( eType == STREAM )
    2416             :     {
    2417             :         // stream
    2418             : 
    2419             :         // Important: Parent storage and output stream must be kept alive until
    2420             :         //            changes have been committed!
    2421             :         uno::Reference< embed::XStorage > xStorage
    2422             :             = m_pProvider->queryStorage(
    2423           0 :                 aUri.getParentUri(), READ_WRITE_CREATE );
    2424           0 :         uno::Reference< io::XOutputStream > xOut;
    2425             : 
    2426           0 :         if ( !xStorage.is() )
    2427           0 :             return false;
    2428             : 
    2429           0 :         if ( xData.is() )
    2430             :         {
    2431             :             // May throw CommandFailedException, DocumentPasswordRequest!
    2432           0 :             xOut = getTruncatedOutputStream( xEnv );
    2433             : 
    2434             :             OSL_ENSURE( xOut.is(), "No target data stream!" );
    2435             : 
    2436             :             try
    2437             :             {
    2438           0 :                 uno::Sequence< sal_Int8 > aBuffer;
    2439           0 :                 sal_Int32 nRead = xData->readSomeBytes( aBuffer, 65536 );
    2440             : 
    2441           0 :                 while ( nRead > 0 )
    2442             :                 {
    2443           0 :                     aBuffer.realloc( nRead );
    2444           0 :                     xOut->writeBytes( aBuffer );
    2445           0 :                     aBuffer.realloc( 0 );
    2446           0 :                     nRead = xData->readSomeBytes( aBuffer, 65536 );
    2447             :                 }
    2448             : 
    2449           0 :                 closeOutputStream( xOut );
    2450             :             }
    2451           0 :             catch ( io::NotConnectedException const & )
    2452             :             {
    2453             :                 // readSomeBytes, writeBytes
    2454             :                 OSL_FAIL( "Caught NotConnectedException!" );
    2455           0 :                 closeOutputStream( xOut );
    2456           0 :                 return false;
    2457             :             }
    2458           0 :             catch ( io::BufferSizeExceededException const & )
    2459             :             {
    2460             :                 // readSomeBytes, writeBytes
    2461             :                 OSL_FAIL( "Caught BufferSizeExceededException!" );
    2462           0 :                 closeOutputStream( xOut );
    2463           0 :                 return false;
    2464             :             }
    2465           0 :             catch ( io::IOException const & )
    2466             :             {
    2467             :                 // readSomeBytes, writeBytes
    2468             :                 OSL_FAIL( "Caught IOException!" );
    2469           0 :                 closeOutputStream( xOut );
    2470           0 :                 return false;
    2471             :             }
    2472           0 :             catch ( ... )
    2473             :             {
    2474           0 :                 closeOutputStream( xOut );
    2475           0 :                 throw;
    2476             :             }
    2477             :         }
    2478             : 
    2479             :         // Commit changes.
    2480           0 :         if ( !commitStorage( xStorage ) )
    2481           0 :             return false;
    2482             :     }
    2483             :     else
    2484             :     {
    2485             :         OSL_FAIL( "Unknown content type!" );
    2486           0 :         return false;
    2487             :     }
    2488           0 :     return true;
    2489             : }
    2490             : 
    2491             : 
    2492           0 : bool Content::renameData(
    2493             :             const uno::Reference< ucb::XContentIdentifier >& xOldId,
    2494             :             const uno::Reference< ucb::XContentIdentifier >& xNewId )
    2495             : {
    2496           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2497             : 
    2498           0 :     ContentType eType = m_aProps.getType();
    2499           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2500             :     {
    2501             :         OSL_FAIL( "renameData not supported by root and documents!" );
    2502           0 :         return false;
    2503             :     }
    2504             : 
    2505           0 :     Uri aOldUri( xOldId->getContentIdentifier() );
    2506             :     uno::Reference< embed::XStorage > xStorage
    2507             :         = m_pProvider->queryStorage(
    2508           0 :             aOldUri.getParentUri(), READ_WRITE_NOCREATE );
    2509             : 
    2510           0 :     if ( !xStorage.is() )
    2511           0 :         return false;
    2512             : 
    2513             :     try
    2514             :     {
    2515           0 :         Uri aNewUri( xNewId->getContentIdentifier() );
    2516           0 :         xStorage->renameElement(
    2517           0 :             aOldUri.getDecodedName(), aNewUri.getDecodedName() );
    2518             :     }
    2519           0 :     catch ( embed::InvalidStorageException const & )
    2520             :     {
    2521             :         // this storage is in invalid state for eny reason
    2522             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2523           0 :         return false;
    2524             :     }
    2525           0 :     catch ( lang::IllegalArgumentException const & )
    2526             :     {
    2527             :         // an illegal argument is provided
    2528             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2529           0 :         return false;
    2530             :     }
    2531           0 :     catch ( container::NoSuchElementException const & )
    2532             :     {
    2533             :         // there is no element with old name in this storage
    2534             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2535           0 :         return false;
    2536             :     }
    2537           0 :     catch ( container::ElementExistException const & )
    2538             :     {
    2539             :         // an element with new name already exists in this storage
    2540             :         OSL_FAIL( "Caught ElementExistException!" );
    2541           0 :         return false;
    2542             :     }
    2543           0 :     catch ( io::IOException const & )
    2544             :     {
    2545             :         // in case of io errors during renaming
    2546             :         OSL_FAIL( "Caught IOException!" );
    2547           0 :         return false;
    2548             :     }
    2549           0 :     catch ( embed::StorageWrappedTargetException const & )
    2550             :     {
    2551             :         // wraps other exceptions
    2552             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2553           0 :         return false;
    2554             :     }
    2555             : 
    2556           0 :     return commitStorage( xStorage );
    2557             : }
    2558             : 
    2559             : 
    2560           0 : bool Content::removeData()
    2561             : {
    2562           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2563             : 
    2564           0 :     ContentType eType = m_aProps.getType();
    2565           0 :     if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
    2566             :     {
    2567             :         OSL_FAIL( "removeData not supported by root and documents!" );
    2568           0 :         return false;
    2569             :     }
    2570             : 
    2571           0 :     Uri aUri( m_xIdentifier->getContentIdentifier() );
    2572             :     uno::Reference< embed::XStorage > xStorage
    2573             :         = m_pProvider->queryStorage(
    2574           0 :             aUri.getParentUri(), READ_WRITE_NOCREATE );
    2575             : 
    2576           0 :     if ( !xStorage.is() )
    2577           0 :         return false;
    2578             : 
    2579             :     try
    2580             :     {
    2581           0 :         xStorage->removeElement( aUri.getDecodedName() );
    2582             :     }
    2583           0 :     catch ( embed::InvalidStorageException const & )
    2584             :     {
    2585             :         // this storage is in invalid state for eny reason
    2586             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2587           0 :         return false;
    2588             :     }
    2589           0 :     catch ( lang::IllegalArgumentException const & )
    2590             :     {
    2591             :         // an illegal argument is provided
    2592             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2593           0 :         return false;
    2594             :     }
    2595           0 :     catch ( container::NoSuchElementException const & )
    2596             :     {
    2597             :         // there is no element with this name in this storage
    2598             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2599           0 :         return false;
    2600             :     }
    2601           0 :     catch ( io::IOException const & )
    2602             :     {
    2603             :         // in case of io errors during renaming
    2604             :         OSL_FAIL( "Caught IOException!" );
    2605           0 :         return false;
    2606             :     }
    2607           0 :     catch ( embed::StorageWrappedTargetException const & )
    2608             :     {
    2609             :         // wraps other exceptions
    2610             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2611           0 :         return false;
    2612             :     }
    2613             : 
    2614           0 :     return commitStorage( xStorage );
    2615             : }
    2616             : 
    2617             : 
    2618           0 : bool Content::copyData( const Uri & rSourceUri, const OUString & rNewName )
    2619             : {
    2620           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2621             : 
    2622           0 :     ContentType eType = m_aProps.getType();
    2623           0 :     if ( ( eType == ROOT ) || ( eType == STREAM ) )
    2624             :     {
    2625             :         OSL_FAIL( "copyData not supported by root and streams!" );
    2626           0 :         return false;
    2627             :     }
    2628             : 
    2629           0 :     Uri aDestUri( m_xIdentifier->getContentIdentifier() );
    2630             :     uno::Reference< embed::XStorage > xDestStorage
    2631           0 :         = m_pProvider->queryStorage( aDestUri.getUri(), READ_WRITE_NOCREATE );
    2632             : 
    2633           0 :     if ( !xDestStorage.is() )
    2634           0 :         return false;
    2635             : 
    2636             :     uno::Reference< embed::XStorage > xSourceStorage
    2637           0 :         = m_pProvider->queryStorage( rSourceUri.getParentUri(), READ );
    2638             : 
    2639           0 :     if ( !xSourceStorage.is() )
    2640           0 :         return false;
    2641             : 
    2642             :     try
    2643             :     {
    2644           0 :         xSourceStorage->copyElementTo( rSourceUri.getDecodedName(),
    2645             :                                        xDestStorage,
    2646           0 :                                        rNewName );
    2647             :     }
    2648           0 :     catch ( embed::InvalidStorageException const & )
    2649             :     {
    2650             :         // this storage is in invalid state for eny reason
    2651             :         OSL_FAIL( "Caught InvalidStorageException!" );
    2652           0 :         return false;
    2653             :     }
    2654           0 :     catch ( lang::IllegalArgumentException const & )
    2655             :     {
    2656             :         // an illegal argument is provided
    2657             :         OSL_FAIL( "Caught IllegalArgumentException!" );
    2658           0 :         return false;
    2659             :     }
    2660           0 :     catch ( container::NoSuchElementException const & )
    2661             :     {
    2662             :         // there is no element with this name in this storage
    2663             :         OSL_FAIL( "Caught NoSuchElementException!" );
    2664           0 :         return false;
    2665             :     }
    2666           0 :     catch ( container::ElementExistException const & )
    2667             :     {
    2668             :         // there is no element with this name in this storage
    2669             :         OSL_FAIL( "Caught ElementExistException!" );
    2670           0 :         return false;
    2671             :     }
    2672           0 :     catch ( io::IOException const & )
    2673             :     {
    2674             :         // in case of io errors during renaming
    2675             :         OSL_FAIL( "Caught IOException!" );
    2676           0 :         return false;
    2677             :     }
    2678           0 :     catch ( embed::StorageWrappedTargetException const & )
    2679             :     {
    2680             :         // wraps other exceptions
    2681             :         OSL_FAIL( "Caught StorageWrappedTargetException!" );
    2682           0 :         return false;
    2683             :     }
    2684             : 
    2685           0 :     return commitStorage( xDestStorage );
    2686             : }
    2687             : 
    2688             : 
    2689             : // static
    2690           0 : bool Content::commitStorage( const uno::Reference< embed::XStorage > & xStorage )
    2691             : {
    2692             :     // Commit changes
    2693           0 :     uno::Reference< embed::XTransactedObject > xTO( xStorage, uno::UNO_QUERY );
    2694             : 
    2695             :     OSL_ENSURE( xTO.is(),
    2696             :                 "Required interface css.embed.XTransactedObject missing!" );
    2697             :     try
    2698             :     {
    2699           0 :         xTO->commit();
    2700             :     }
    2701           0 :     catch ( io::IOException const & )
    2702             :     {
    2703             :         OSL_FAIL( "Caught IOException!" );
    2704           0 :         return false;
    2705             :     }
    2706           0 :     catch ( lang::WrappedTargetException const & )
    2707             :     {
    2708             :         OSL_FAIL( "Caught WrappedTargetException!" );
    2709           0 :         return false;
    2710             :     }
    2711             : 
    2712           0 :     return true;
    2713             : }
    2714             : 
    2715             : 
    2716             : // static
    2717           0 : bool Content::closeOutputStream(
    2718             :     const uno::Reference< io::XOutputStream > & xOut )
    2719             : {
    2720           0 :     if ( xOut.is() )
    2721             :     {
    2722             :         try
    2723             :         {
    2724           0 :             xOut->closeOutput();
    2725           0 :             return true;
    2726             :         }
    2727           0 :         catch ( io::NotConnectedException const & )
    2728             :         {
    2729             :             OSL_FAIL( "Caught NotConnectedException!" );
    2730             :         }
    2731           0 :         catch ( io::BufferSizeExceededException const & )
    2732             :         {
    2733             :             OSL_FAIL( "Caught BufferSizeExceededException!" );
    2734             :         }
    2735           0 :         catch ( io::IOException const & )
    2736             :         {
    2737             :             OSL_FAIL( "Caught IOException!" );
    2738             :         }
    2739             :     }
    2740           0 :     return false;
    2741             : }
    2742             : 
    2743             : 
    2744           0 : static OUString obtainPassword(
    2745             :         const OUString & rName,
    2746             :         task::PasswordRequestMode eMode,
    2747             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2748             :     throw ( ucb::CommandFailedException,
    2749             :             task::DocumentPasswordRequest )
    2750             : {
    2751             :     rtl::Reference< DocumentPasswordRequest > xRequest
    2752           0 :         = new DocumentPasswordRequest( eMode, rName );
    2753             : 
    2754           0 :     if ( xEnv.is() )
    2755             :     {
    2756             :         uno::Reference< task::XInteractionHandler > xIH
    2757           0 :             = xEnv->getInteractionHandler();
    2758           0 :         if ( xIH.is() )
    2759             :         {
    2760           0 :             xIH->handle( xRequest.get() );
    2761             : 
    2762             :             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
    2763           0 :                 = xRequest->getSelection();
    2764             : 
    2765           0 :             if ( xSelection.is() )
    2766             :             {
    2767             :                 // Handler handled the request.
    2768             :                 uno::Reference< task::XInteractionAbort > xAbort(
    2769           0 :                     xSelection.get(), uno::UNO_QUERY );
    2770           0 :                 if ( xAbort.is() )
    2771             :                 {
    2772             :                     throw ucb::CommandFailedException(
    2773             :                         OUString( "Abort requested by Interaction Handler."  ),
    2774             :                         uno::Reference< uno::XInterface >(),
    2775           0 :                         xRequest->getRequest() );
    2776             :                 }
    2777             : 
    2778             :                 uno::Reference< task::XInteractionPassword > xPassword(
    2779           0 :                     xSelection.get(), uno::UNO_QUERY );
    2780           0 :                 if ( xPassword.is() )
    2781             :                 {
    2782           0 :                     return xPassword->getPassword();
    2783             :                 }
    2784             : 
    2785             :                 // Unknown selection. Should never happen.
    2786             :                 throw ucb::CommandFailedException(
    2787             :                     OUString( "Interaction Handler selected unknown continuation!"  ),
    2788             :                     uno::Reference< uno::XInterface >(),
    2789           0 :                     xRequest->getRequest() );
    2790           0 :             }
    2791           0 :         }
    2792             :     }
    2793             : 
    2794             :     // No IH or IH did not handle exception.
    2795           0 :     task::DocumentPasswordRequest aRequest;
    2796           0 :     xRequest->getRequest() >>= aRequest;
    2797           0 :     throw aRequest;
    2798             : }
    2799             : 
    2800             : 
    2801           0 : uno::Reference< io::XInputStream > Content::getInputStream(
    2802             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2803             :     throw ( ucb::CommandFailedException,
    2804             :             task::DocumentPasswordRequest,
    2805             :             uno::RuntimeException )
    2806             : {
    2807           0 :     OUString aUri;
    2808           0 :     OUString aPassword;
    2809           0 :     bool bPasswordRequested = false;
    2810             : 
    2811             :     {
    2812           0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2813             : 
    2814             :         OSL_ENSURE( m_aProps.getType() == STREAM,
    2815             :                     "Content::getInputStream - content is no stream!" );
    2816             : 
    2817           0 :         aUri = Uri( m_xIdentifier->getContentIdentifier() ).getUri();
    2818             :     }
    2819             : 
    2820             :     for ( ;; )
    2821             :     {
    2822             :         try
    2823             :         {
    2824           0 :             osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2825             :             return uno::Reference< io::XInputStream >(
    2826           0 :                 m_pProvider->queryInputStream( aUri, aPassword ) );
    2827             :         }
    2828           0 :         catch ( packages::WrongPasswordException const & )
    2829             :         {
    2830             :             // Obtain (new) password.
    2831             :             aPassword
    2832           0 :                 = obtainPassword( aUri, /* @@@ find better title */
    2833             :                                   bPasswordRequested
    2834             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2835             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2836           0 :                                    xEnv );
    2837           0 :             bPasswordRequested = true;
    2838             :         }
    2839           0 :     }
    2840             : }
    2841             : 
    2842             : 
    2843           0 : static uno::Reference< io::XOutputStream > lcl_getTruncatedOutputStream(
    2844             :                 const OUString & rUri,
    2845             :                 ContentProvider * pProvider,
    2846             :                 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2847             :     throw ( ucb::CommandFailedException,
    2848             :             task::DocumentPasswordRequest,
    2849             :             uno::RuntimeException )
    2850             : {
    2851           0 :     OUString aPassword;
    2852           0 :     bool bPasswordRequested = false;
    2853             :     for ( ;; )
    2854             :     {
    2855             :         try
    2856             :         {
    2857             :             return uno::Reference< io::XOutputStream >(
    2858             :                 pProvider->queryOutputStream(
    2859           0 :                     rUri, aPassword, true /* truncate */ ) );
    2860             :         }
    2861           0 :         catch ( packages::WrongPasswordException const & )
    2862             :         {
    2863             :             // Obtain (new) password.
    2864             :             aPassword
    2865           0 :                 = obtainPassword( rUri, /* @@@ find better title */
    2866             :                                   bPasswordRequested
    2867             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2868             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2869           0 :                                    xEnv );
    2870           0 :             bPasswordRequested = true;
    2871             :         }
    2872           0 :     }
    2873             : }
    2874             : 
    2875             : 
    2876           0 : uno::Reference< io::XOutputStream > Content::getTruncatedOutputStream(
    2877             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2878             :     throw ( ucb::CommandFailedException,
    2879             :             task::DocumentPasswordRequest,
    2880             :             css::uno::RuntimeException )
    2881             : {
    2882             :     OSL_ENSURE( m_aProps.getType() == STREAM,
    2883             :                 "Content::getTruncatedOutputStream - content is no stream!" );
    2884             : 
    2885             :     return lcl_getTruncatedOutputStream(
    2886           0 :             Uri( m_xIdentifier->getContentIdentifier() ).getUri(),
    2887             :             m_pProvider,
    2888           0 :             xEnv );
    2889             : }
    2890             : 
    2891             : 
    2892           0 : uno::Reference< io::XStream > Content::getStream(
    2893             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    2894             :     throw ( ucb::CommandFailedException,
    2895             :             task::DocumentPasswordRequest,
    2896             :             uno::RuntimeException )
    2897             : {
    2898           0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
    2899             : 
    2900             :     OSL_ENSURE( m_aProps.getType() == STREAM,
    2901             :                 "Content::getStream - content is no stream!" );
    2902             : 
    2903           0 :     OUString aUri( Uri( m_xIdentifier->getContentIdentifier() ).getUri() );
    2904           0 :     OUString aPassword;
    2905           0 :     bool bPasswordRequested = false;
    2906             :     for ( ;; )
    2907             :     {
    2908             :         try
    2909             :         {
    2910             :             return uno::Reference< io::XStream >(
    2911             :                 m_pProvider->queryStream(
    2912           0 :                     aUri, aPassword, false /* no truncate */ ) );
    2913             :         }
    2914           0 :         catch ( packages::WrongPasswordException const & )
    2915             :         {
    2916             :             // Obtain (new) password.
    2917             :             aPassword
    2918           0 :                 = obtainPassword( aUri, /* @@@ find better title */
    2919             :                                   bPasswordRequested
    2920             :                                    ? task::PasswordRequestMode_PASSWORD_REENTER
    2921             :                                    : task::PasswordRequestMode_PASSWORD_ENTER,
    2922           0 :                                    xEnv );
    2923           0 :             bPasswordRequested = true;
    2924             :         }
    2925           0 :     }
    2926             : }
    2927             : 
    2928             : 
    2929             : 
    2930             : 
    2931             : // ContentProperties Implementation.
    2932             : 
    2933             : 
    2934             : 
    2935             : 
    2936             : uno::Sequence< ucb::ContentInfo >
    2937           0 : ContentProperties::getCreatableContentsInfo() const
    2938             : {
    2939           0 :     if ( isContentCreator() )
    2940             :     {
    2941           0 :         uno::Sequence< beans::Property > aProps( 1 );
    2942           0 :         aProps.getArray()[ 0 ] = beans::Property(
    2943             :                     OUString("Title"),
    2944             :                     -1,
    2945           0 :                     cppu::UnoType<OUString>::get(),
    2946           0 :                     beans::PropertyAttribute::BOUND );
    2947             : 
    2948             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2949           0 :         if ( getType() == DOCUMENT )
    2950             :         {
    2951             :             // streams cannot be created as direct children of document root
    2952           0 :             uno::Sequence< ucb::ContentInfo > aSeq( 1 );
    2953             : 
    2954             :             // Folder.
    2955           0 :             aSeq.getArray()[ 0 ].Type = TDOC_FOLDER_CONTENT_TYPE;
    2956           0 :             aSeq.getArray()[ 0 ].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
    2957           0 :             aSeq.getArray()[ 0 ].Properties = aProps;
    2958             : 
    2959           0 :             return aSeq;
    2960             :         }
    2961             :         else
    2962             :         {
    2963             : #endif
    2964           0 :             uno::Sequence< ucb::ContentInfo > aSeq( 2 );
    2965             : 
    2966             :             // Folder.
    2967           0 :             aSeq.getArray()[ 0 ].Type = TDOC_FOLDER_CONTENT_TYPE;
    2968           0 :             aSeq.getArray()[ 0 ].Attributes
    2969           0 :                 = ucb::ContentInfoAttribute::KIND_FOLDER;
    2970           0 :             aSeq.getArray()[ 0 ].Properties = aProps;
    2971             : 
    2972             :             // Stream.
    2973           0 :             aSeq.getArray()[ 1 ].Type = TDOC_STREAM_CONTENT_TYPE;
    2974           0 :             aSeq.getArray()[ 1 ].Attributes
    2975             :                 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
    2976           0 :                   | ucb::ContentInfoAttribute::KIND_DOCUMENT;
    2977           0 :             aSeq.getArray()[ 1 ].Properties = aProps;
    2978             : 
    2979           0 :             return aSeq;
    2980             : #ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
    2981           0 :         }
    2982             : #endif
    2983             :     }
    2984             :     else
    2985             :     {
    2986             :         OSL_FAIL( "getCreatableContentsInfo called on non-contentcreator "
    2987             :                     "object!" );
    2988             : 
    2989           0 :         return uno::Sequence< ucb::ContentInfo >( 0 );
    2990             :     }
    2991             : }
    2992             : 
    2993             : 
    2994           0 : bool ContentProperties::isContentCreator() const
    2995             : {
    2996           0 :     return ( getType() == FOLDER ) || ( getType() == DOCUMENT );
    2997             : }
    2998             : 
    2999             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11