blob: 0500a0aeb8d0fef32c77298d1ea22d48fef8ca79 [file] [log] [blame]
/**************************************************************
*
* 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