/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_ucbhelper.hxx" /************************************************************************** TODO ************************************************************************** *************************************************************************/ #include "osl/diagnose.h" #include "com/sun/star/beans/PropertyAttribute.hpp" #include "com/sun/star/beans/XPropertyAccess.hpp" #include "com/sun/star/lang/IllegalAccessException.hpp" #include "com/sun/star/sdbc/XRow.hpp" #include "com/sun/star/ucb/XCommandInfo.hpp" #include "com/sun/star/ucb/XPersistentPropertySet.hpp" #include "ucbhelper/contentidentifier.hxx" #include "ucbhelper/propertyvalueset.hxx" #include "ucbhelper/cancelcommandexecution.hxx" #include "myucp_content.hxx" #include "myucp_provider.hxx" #ifdef IMPLEMENT_COMMAND_INSERT #include "com/sun/star/ucb/InsertCommandArgument.hpp" #include "com/sun/star/ucb/MissingInputStreamException.hpp" #include "com/sun/star/ucb/MissingPropertiesException.hpp" #endif #ifdef IMPLEMENT_COMMAND_OPEN #include "com/sun/star/io/XOutputStream.hpp" #include "com/sun/star/io/XActiveDataSink.hpp" #include "com/sun/star/ucb/OpenCommandArgument2.hpp" #include "com/sun/star/ucb/OpenMode.hpp" #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp" #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp" #include "myucp_resultset.hxx" #endif using namespace com::sun::star; // @@@ Adjust namespace name. using namespace myucp; //========================================================================= //========================================================================= // // Content Implementation. // //========================================================================= //========================================================================= Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, ::ucbhelper::ContentProviderImplHelper* pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier ) : ContentImplHelper( rxSMgr, pProvider, Identifier ) { // @@@ Fill m_aProps here or implement lazy evaluation logic for this. // m_aProps.aTitle = // m_aprops.aContentType = // m_aProps.bIsDocument = // m_aProps.bIsFolder = } //========================================================================= // virtual Content::~Content() { } //========================================================================= // // XInterface methods. // //========================================================================= // virtual void SAL_CALL Content::acquire() throw() { ContentImplHelper::acquire(); } //========================================================================= // virtual void SAL_CALL Content::release() throw() { ContentImplHelper::release(); } //========================================================================= // virtual uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException ) { uno::Any aRet; // @@@ Add support for additional interfaces. #if 0 aRet = cppu::queryInterface( rType, static_cast< yyy::Xxxxxxxxx * >( this ) ); #endif return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); } //========================================================================= // // XTypeProvider methods. // //========================================================================= XTYPEPROVIDER_COMMON_IMPL( Content ); //========================================================================= // virtual uno::Sequence< uno::Type > SAL_CALL Content::getTypes() throw( uno::RuntimeException ) { // @@@ Add own interfaces. static cppu::OTypeCollection* pCollection = 0; if ( !pCollection ) { osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); if ( !pCollection ) { static cppu::OTypeCollection aCollection( CPPU_TYPE_REF( lang::XTypeProvider ), CPPU_TYPE_REF( lang::XServiceInfo ), CPPU_TYPE_REF( lang::XComponent ), CPPU_TYPE_REF( ucb::XContent ), CPPU_TYPE_REF( ucb::XCommandProcessor ), CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), CPPU_TYPE_REF( beans::XPropertyContainer ), CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), CPPU_TYPE_REF( container::XChild ) ); pCollection = &aCollection; } } return (*pCollection).getTypes(); } //========================================================================= // // XServiceInfo methods. // //========================================================================= // virtual rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException ) { // @@@ Adjust implementation name. // Prefix with reversed company domain name. return rtl::OUString::createFromAscii( "com.sun.star.comp.myucp.Content" ); } //========================================================================= // virtual uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() throw( uno::RuntimeException ) { // @@@ Adjust macro name. uno::Sequence< rtl::OUString > aSNS( 1 ); aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); return aSNS; } //========================================================================= // // XContent methods. // //========================================================================= // virtual rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException ) { // @@@ Adjust macro name ( def in myucp_provider.hxx ). return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); } //========================================================================= // // XCommandProcessor methods. // //========================================================================= // virtual uno::Any SAL_CALL Content::execute( const ucb::Command& aCommand, sal_Int32 /* CommandId */, const uno::Reference< ucb::XCommandEnvironment >& Environment ) throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException ) { uno::Any aRet; if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) ) { ////////////////////////////////////////////////////////////////// // getPropertyValues ////////////////////////////////////////////////////////////////// uno::Sequence< beans::Property > Properties; if ( !( aCommand.Argument >>= Properties ) ) { OSL_ENSURE( sal_False, "Wrong argument type!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), -1 ) ), Environment ); // Unreachable } aRet <<= getPropertyValues( Properties, Environment ); } else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) ) { ////////////////////////////////////////////////////////////////// // setPropertyValues ////////////////////////////////////////////////////////////////// uno::Sequence< beans::PropertyValue > aProperties; if ( !( aCommand.Argument >>= aProperties ) ) { OSL_ENSURE( sal_False, "Wrong argument type!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), -1 ) ), Environment ); // Unreachable } if ( !aProperties.getLength() ) { OSL_ENSURE( sal_False, "No properties!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), -1 ) ), Environment ); // Unreachable } aRet <<= setPropertyValues( aProperties, Environment ); } else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) ) { ////////////////////////////////////////////////////////////////// // getPropertySetInfo ////////////////////////////////////////////////////////////////// // Note: Implemented by base class. aRet <<= getPropertySetInfo( Environment ); } else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) ) { ////////////////////////////////////////////////////////////////// // getCommandInfo ////////////////////////////////////////////////////////////////// // Note: Implemented by base class. aRet <<= getCommandInfo( Environment ); } #ifdef IMPLEMENT_COMMAND_OPEN else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "open" ) ) ) { ucb::OpenCommandArgument2 aOpenCommand; if ( !( aCommand.Argument >>= aOpenCommand ) ) { OSL_ENSURE( sal_False, "Wrong argument type!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), -1 ) ), Environment ); // Unreachable } sal_Bool bOpenFolder = ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) || ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) || ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) ); if ( bOpenFolder /*&& isFolder( Environment )*/ ) { // open as folder - return result set uno::Reference< ucb::XDynamicResultSet > xSet = new DynamicResultSet( m_xSMgr, this, aOpenCommand, Environment ); aRet <<= xSet; } if ( aOpenCommand.Sink.is() ) { // Open document - supply document data stream. // Check open mode if ( ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) { // Unsupported. ::ucbhelper::cancelCommandExecution( uno::makeAny( ucb::UnsupportedOpenModeException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), sal_Int16( aOpenCommand.Mode ) ) ), Environment ); // Unreachable } rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >( aOpenCommand.Sink, uno::UNO_QUERY ); if ( xOut.is() ) { // @@@ write data into xOut } else { uno::Reference< io::XActiveDataSink > xDataSink( aOpenCommand.Sink, uno::UNO_QUERY ); if ( xDataSink.is() ) { uno::Reference< io::XInputStream > xIn /* @@@ your XInputStream + XSeekable impl. object */; xDataSink->setInputStream( xIn ); } else { // Note: aOpenCommand.Sink may contain an XStream // implementation. Support for this type of // sink is optional... ::ucbhelper::cancelCommandExecution( uno::makeAny( ucb::UnsupportedDataSinkException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), aOpenCommand.Sink ) ), Environment ); // Unreachable } } } } #endif // IMPLEMENT_COMMAND_OPEN #ifdef IMPLEMENT_COMMAND_INSERT else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) { ////////////////////////////////////////////////////////////////// // insert ////////////////////////////////////////////////////////////////// ucb::InsertCommandArgument arg; if ( !( aCommand.Argument >>= arg ) ) { OSL_ENSURE( sal_False, "Wrong argument type!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( lang::IllegalArgumentException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), -1 ) ), Environment ); // Unreachable } insert( arg.Data, arg.ReplaceExisting, Environment ); } #endif // IMPLEMENT_COMMAND_INSERT #ifdef IMPLEMENT_COMMAND_DELETE else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) { ////////////////////////////////////////////////////////////////// // delete ////////////////////////////////////////////////////////////////// sal_Bool bDeletePhysical = sal_False; aCommand.Argument >>= bDeletePhysical; destroy( bDeletePhysical ); // Remove own and all children's Additional Core Properties. removeAdditionalPropertySet( sal_True ); // Remove own and all childrens(!) persistent data. // removeData(); } #endif // IMPLEMENT_COMMAND_DELETE else { ////////////////////////////////////////////////////////////////// // Unsupported command ////////////////////////////////////////////////////////////////// OSL_ENSURE( sal_False, "Content::execute - unsupported command!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( ucb::UnsupportedCommandException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ), Environment ); // Unreachable } return aRet; } //========================================================================= // virtual void SAL_CALL Content::abort( sal_Int32 ) throw( uno::RuntimeException ) { // @@@ Implement logic to abort running commands, if this makes // sense for your content. } //========================================================================= // // Non-interface methods. // //========================================================================= // virtual rtl::OUString Content::getParentURL() { rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); // @@@ Extract URL of parent from aURL and return it... return rtl::OUString(); } //========================================================================= // static uno::Reference< sdbc::XRow > Content::getPropertyValues( const uno::Reference< lang::XMultiServiceFactory >& rSMgr, const uno::Sequence< beans::Property >& rProperties, const ContentProperties& rData, const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider, const rtl::OUString& rContentId ) { // Note: Empty sequence means "get values of all supported properties". rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( rSMgr ); sal_Int32 nCount = rProperties.getLength(); if ( nCount ) { uno::Reference< beans::XPropertySet > xAdditionalPropSet; sal_Bool bTriedToGetAdditonalPropSet = sal_False; const beans::Property* pProps = rProperties.getConstArray(); for ( sal_Int32 n = 0; n < nCount; ++n ) { const beans::Property& rProp = pProps[ n ]; // Process Core properties. if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) { xRow->appendString ( rProp, rData.aContentType ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) { xRow->appendString ( rProp, rData.aTitle ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) { xRow->appendBoolean( rProp, rData.bIsDocument ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) { xRow->appendBoolean( rProp, rData.bIsFolder ); } // @@@ Process other properties supported directly. #if 0 else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) ) { } #endif else { // @@@ Note: If your data source supports adding/removing // properties, you should implement the interface // XPropertyContainer by yourself and supply your own // logic here. The base class uses the service // "com.sun.star.ucb.Store" to maintain Additional Core // properties. But using server functionality is preferred! // Not a Core Property! Maybe it's an Additional Core Property?! if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) { xAdditionalPropSet = uno::Reference< beans::XPropertySet >( rProvider->getAdditionalPropertySet( rContentId, sal_False ), uno::UNO_QUERY ); bTriedToGetAdditonalPropSet = sal_True; } if ( xAdditionalPropSet.is() ) { if ( !xRow->appendPropertySetValue( xAdditionalPropSet, rProp ) ) { // Append empty entry. xRow->appendVoid( rProp ); } } else { // Append empty entry. xRow->appendVoid( rProp ); } } } } else { // Append all Core Properties. xRow->appendString ( beans::Property( rtl::OUString::createFromAscii( "ContentType" ), -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), rData.aContentType ); xRow->appendString ( beans::Property( rtl::OUString::createFromAscii( "Title" ), -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ), beans::PropertyAttribute::BOUND ), rData.aTitle ); xRow->appendBoolean( beans::Property( rtl::OUString::createFromAscii( "IsDocument" ), -1, getCppuBooleanType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), rData.bIsDocument ); xRow->appendBoolean( beans::Property( rtl::OUString::createFromAscii( "IsFolder" ), -1, getCppuBooleanType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ), rData.bIsFolder ); // @@@ Append other properties supported directly. // @@@ Note: If your data source supports adding/removing // properties, you should implement the interface // XPropertyContainer by yourself and supply your own // logic here. The base class uses the service // "com.sun.star.ucb.Store" to maintain Additional Core // properties. But using server functionality is preferred! // Append all Additional Core Properties. uno::Reference< beans::XPropertySet > xSet( rProvider->getAdditionalPropertySet( rContentId, sal_False ), uno::UNO_QUERY ); xRow->appendPropertySet( xSet ); } return uno::Reference< sdbc::XRow >( xRow.get() ); } //========================================================================= uno::Reference< sdbc::XRow > Content::getPropertyValues( const uno::Sequence< beans::Property >& rProperties, const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */) { osl::Guard< osl::Mutex > aGuard( m_aMutex ); return getPropertyValues( m_xSMgr, rProperties, m_aProps, rtl::Reference< ::ucbhelper::ContentProviderImplHelper >( m_xProvider.get() ), m_xIdentifier->getContentIdentifier() ); } //========================================================================= uno::Sequence< uno::Any > Content::setPropertyValues( const uno::Sequence< beans::PropertyValue >& rValues, const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */) { osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); uno::Sequence< uno::Any > aRet( rValues.getLength() ); uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() ); sal_Int32 nChanged = 0; beans::PropertyChangeEvent aEvent; aEvent.Source = static_cast< cppu::OWeakObject * >( this ); aEvent.Further = sal_False; // aEvent.PropertyName = aEvent.PropertyHandle = -1; // aEvent.OldValue = // aEvent.NewValue = const beans::PropertyValue* pValues = rValues.getConstArray(); sal_Int32 nCount = rValues.getLength(); uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet; sal_Bool bTriedToGetAdditonalPropSet = sal_False; for ( sal_Int32 n = 0; n < nCount; ++n ) { const beans::PropertyValue& rValue = pValues[ n ]; if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) { // Read-only property! aRet[ n ] <<= lang::IllegalAccessException( rtl::OUString::createFromAscii( "Property is read-only!" ), static_cast< cppu::OWeakObject * >( this ) ); } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) { // Read-only property! aRet[ n ] <<= lang::IllegalAccessException( rtl::OUString::createFromAscii( "Property is read-only!" ), static_cast< cppu::OWeakObject * >( this ) ); } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) { // Read-only property! aRet[ n ] <<= lang::IllegalAccessException( rtl::OUString::createFromAscii( "Property is read-only!" ), static_cast< cppu::OWeakObject * >( this ) ); } else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) { rtl::OUString aNewValue; if ( rValue.Value >>= aNewValue ) { if ( aNewValue != m_aProps.aTitle ) { aEvent.PropertyName = rValue.Name; aEvent.OldValue = uno::makeAny( m_aProps.aTitle ); aEvent.NewValue = uno::makeAny( aNewValue ); aChanges.getArray()[ nChanged ] = aEvent; m_aProps.aTitle = aNewValue; nChanged++; } else { // Old value equals new value. No error! } } else { aRet[ n ] <<= beans::IllegalTypeException( rtl::OUString::createFromAscii( "Property value has wrong type!" ), static_cast< cppu::OWeakObject * >( this ) ); } } // @@@ Process other properties supported directly. #if 0 else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) ) { } #endif else { // @@@ Note: If your data source supports adding/removing // properties, you should implement the interface // XPropertyContainer by yourself and supply your own // logic here. The base class uses the service // "com.sun.star.ucb.Store" to maintain Additional Core // properties. But using server functionality is preferred! // Not a Core Property! Maybe it's an Additional Core Property?! if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) { xAdditionalPropSet = getAdditionalPropertySet( sal_False ); bTriedToGetAdditonalPropSet = sal_True; } if ( xAdditionalPropSet.is() ) { try { uno::Any aOldValue = xAdditionalPropSet->getPropertyValue( rValue.Name ); if ( aOldValue != rValue.Value ) { xAdditionalPropSet->setPropertyValue( rValue.Name, rValue.Value ); aEvent.PropertyName = rValue.Name; aEvent.OldValue = aOldValue; aEvent.NewValue = rValue.Value; aChanges.getArray()[ nChanged ] = aEvent; nChanged++; } else { // Old value equals new value. No error! } } catch ( beans::UnknownPropertyException const & e ) { aRet[ n ] <<= e; } catch ( lang::WrappedTargetException const & e ) { aRet[ n ] <<= e; } catch ( beans::PropertyVetoException const & e ) { aRet[ n ] <<= e; } catch ( lang::IllegalArgumentException const & e ) { aRet[ n ] <<= e; } } else { aRet[ n ] <<= uno::Exception( rtl::OUString::createFromAscii( "No property set for storing the value!" ), static_cast< cppu::OWeakObject * >( this ) ); } } } if ( nChanged > 0 ) { // @@@ Save changes. // storeData(); aGuard.clear(); aChanges.realloc( nChanged ); notifyPropertiesChange( aChanges ); } return aRet; } #ifdef IMPLEMENT_COMMAND_INSERT //========================================================================= void Content::queryChildren( ContentRefList& rChildren ) { // @@@ Adapt method to your URL scheme... // Obtain a list with a snapshot of all currently instanciated contents // from provider and extract the contents which are direct children // of this content. ::ucbhelper::ContentRefList aAllContents; m_xProvider->queryExistingContents( aAllContents ); ::rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); sal_Int32 nPos = aURL.lastIndexOf( '/' ); if ( nPos != ( aURL.getLength() - 1 ) ) { // No trailing slash found. Append. aURL += ::rtl::OUString::createFromAscii( "/" ); } sal_Int32 nLen = aURL.getLength(); ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin(); ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end(); while ( it != end ) { ::ucbhelper::ContentImplHelperRef xChild = (*it); ::rtl::OUString aChildURL = xChild->getIdentifier()->getContentIdentifier(); // Is aURL a prefix of aChildURL? if ( ( aChildURL.getLength() > nLen ) && ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) { nPos = aChildURL.indexOf( '/', nLen ); if ( ( nPos == -1 ) || ( nPos == ( aChildURL.getLength() - 1 ) ) ) { // No further slashes / only a final slash. It's a child! rChildren.push_back( ContentRef( static_cast< Content * >( xChild.get() ) ) ); } } ++it; } } //========================================================================= void Content::insert( const uno::Reference< io::XInputStream > & xInputStream, sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment >& Environment ) throw( uno::Exception ) { osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); // Check, if all required properties were set. #if 0 // @@@ add checks for property presence if ( m_aProps.xxxx == yyyyy ) { OSL_ENSURE( sal_False, "Content::insert - property value missing!" ); uno::Sequence< rtl::OUString > aProps( 1 ); aProps[ 0 ] = rtl::OUString::createFromAscii( "zzzz" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( ucb::MissingPropertiesException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ), aProps ) ), Environment ); // Unreachable } #endif bool bNeedInputStream = true; // @@@ adjust to real requirements if ( bNeedInputStream && !xInputStream.is() ) { OSL_ENSURE( sal_False, "Content::insert - No data stream!" ); ::ucbhelper::cancelCommandExecution( uno::makeAny( ucb::MissingInputStreamException( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ), Environment ); // Unreachable } // Assemble new content identifier... uno::Reference< ucb::XContentIdentifier > xId /* @@@ create content identifier */; // Fail, if a resource with given id already exists. if ( !bReplaceExisting /*&& hasData( xId ) @@@ impl for hasData() */ ) { uno::Any aProps = uno::makeAny( beans::PropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), -1, uno::makeAny( xId->getContentIdentifier() ), beans::PropertyState_DIRECT_VALUE ) ); ucbhelper::cancelCommandExecution( ucb::IOErrorCode_ALREADY_EXISTING, uno::Sequence< uno::Any >(&aProps, 1), Environment, rtl::OUString::createFromAscii( "content already existing!!" ), this ); // Unreachable } m_xIdentifier = xId; // @@@ // storeData(); aGuard.clear(); inserted(); } #endif // IMPLEMENT_COMMAND_INSERT #ifdef IMPLEMENT_COMMAND_DELETE //========================================================================= void Content::destroy( sal_Bool bDeletePhysical ) throw( uno::Exception ) { // @@@ take care about bDeletePhysical -> trashcan support uno::Reference< ucb::XContent > xThis = this; deleted(); osl::Guard< osl::Mutex > aGuard( m_aMutex ); // Process instanciated children... ContentRefList aChildren; queryChildren( aChildren ); ContentRefList::const_iterator it = aChildren.begin(); ContentRefList::const_iterator end = aChildren.end(); while ( it != end ) { (*it)->destroy( bDeletePhysical ); ++it; } } #endif // IMPLEMENT_COMMAND_DELETE