summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/tdoc
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/tdoc')
-rw-r--r--ucb/source/ucp/tdoc/makefile.mk94
-rw-r--r--ucb/source/ucp/tdoc/tdoc_content.cxx3135
-rw-r--r--ucb/source/ucp/tdoc/tdoc_content.hxx342
-rw-r--r--ucb/source/ucp/tdoc/tdoc_contentcaps.cxx705
-rw-r--r--ucb/source/ucp/tdoc/tdoc_datasupplier.cxx468
-rw-r--r--ucb/source/ucp/tdoc/tdoc_datasupplier.hxx81
-rw-r--r--ucb/source/ucp/tdoc/tdoc_docmgr.cxx691
-rw-r--r--ucb/source/ucp/tdoc/tdoc_docmgr.hxx173
-rw-r--r--ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx188
-rw-r--r--ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx86
-rw-r--r--ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx242
-rw-r--r--ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx100
-rw-r--r--ucb/source/ucp/tdoc/tdoc_provider.cxx629
-rw-r--r--ucb/source/ucp/tdoc/tdoc_provider.hxx148
-rw-r--r--ucb/source/ucp/tdoc/tdoc_resultset.cxx95
-rw-r--r--ucb/source/ucp/tdoc/tdoc_resultset.hxx56
-rw-r--r--ucb/source/ucp/tdoc/tdoc_services.cxx151
-rw-r--r--ucb/source/ucp/tdoc/tdoc_stgelems.cxx1108
-rw-r--r--ucb/source/ucp/tdoc/tdoc_stgelems.hxx542
-rw-r--r--ucb/source/ucp/tdoc/tdoc_storage.cxx712
-rw-r--r--ucb/source/ucp/tdoc/tdoc_storage.hxx172
-rw-r--r--ucb/source/ucp/tdoc/tdoc_uri.cxx135
-rw-r--r--ucb/source/ucp/tdoc/tdoc_uri.hxx131
-rw-r--r--ucb/source/ucp/tdoc/ucptdoc.xml129
24 files changed, 10313 insertions, 0 deletions
diff --git a/ucb/source/ucp/tdoc/makefile.mk b/ucb/source/ucp/tdoc/makefile.mk
new file mode 100644
index 000000000000..83e9599eed72
--- /dev/null
+++ b/ucb/source/ucp/tdoc/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=ucb
+# Version
+UCPTDOC_MAJOR=1
+TARGET=ucptdoc$(UCPTDOC_MAJOR).uno
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+
+# no "lib" prefix
+DLLPRE =
+
+SLOFILES=\
+ $(SLO)$/tdoc_provider.obj \
+ $(SLO)$/tdoc_services.obj \
+ $(SLO)$/tdoc_uri.obj \
+ $(SLO)$/tdoc_content.obj \
+ $(SLO)$/tdoc_contentcaps.obj \
+ $(SLO)$/tdoc_storage.obj \
+ $(SLO)$/tdoc_docmgr.obj \
+ $(SLO)$/tdoc_datasupplier.obj \
+ $(SLO)$/tdoc_resultset.obj \
+ $(SLO)$/tdoc_documentcontentfactory.obj \
+ $(SLO)$/tdoc_passwordrequest.obj \
+ $(SLO)$/tdoc_stgelems.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# Make symbol renaming match library name for Mac OS X
+.IF "$(OS)"=="MACOSX"
+SYMBOLPREFIX=$(TARGET)
+.ENDIF
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # L10N_framework
+
+# --- Targets ----------------------------------------------------------
+
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/tdoc/tdoc_content.cxx b/ucb/source/ucp/tdoc/tdoc_content.cxx
new file mode 100644
index 000000000000..2c2103e46224
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_content.cxx
@@ -0,0 +1,3135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "osl/diagnose.h"
+#include "osl/doublecheckedlocking.h"
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/io/XActiveDataStreamer.hpp"
+#include "com/sun/star/lang/IllegalAccessException.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/ucb/ContentAction.hpp"
+#include "com/sun/star/ucb/ContentInfoAttribute.hpp"
+#include "com/sun/star/ucb/InsertCommandArgument.hpp"
+#include "com/sun/star/ucb/InteractiveBadTransferURLException.hpp"
+#include "com/sun/star/ucb/MissingInputStreamException.hpp"
+#include "com/sun/star/ucb/MissingPropertiesException.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/NameClashException.hpp"
+#include "com/sun/star/ucb/OpenCommandArgument2.hpp"
+#include "com/sun/star/ucb/OpenMode.hpp"
+#include "com/sun/star/ucb/TransferInfo.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
+#include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
+#include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
+#include "com/sun/star/ucb/XCommandInfo.hpp"
+#include "com/sun/star/ucb/XPersistentPropertySet.hpp"
+
+#include "ucbhelper/cancelcommandexecution.hxx"
+#include "ucbhelper/contentidentifier.hxx"
+#include "ucbhelper/propertyvalueset.hxx"
+
+#include "tdoc_content.hxx"
+#include "tdoc_resultset.hxx"
+#include "tdoc_passwordrequest.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+static ContentType lcl_getContentType( const rtl::OUString & rType )
+{
+ if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_ROOT_CONTENT_TYPE ) ) )
+ return ROOT;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_DOCUMENT_CONTENT_TYPE ) ) )
+ return DOCUMENT;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) ) )
+ return FOLDER;
+ else if ( rType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ return STREAM;
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "Content::Content - unsupported content type string" );
+ return STREAM;
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Content Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ // Fail, if resource does not exist.
+ ContentProperties aProps;
+ if ( !Content::loadData( pProvider,
+ Uri( Identifier->getContentIdentifier() ),
+ aProps ) )
+ return 0;
+
+ return new Content( rxSMgr, pProvider, Identifier, aProps );
+}
+
+//=========================================================================
+// static ( "virtual" ctor )
+Content* Content::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+{
+ if ( !Info.Type.getLength() )
+ return 0;
+
+ if ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) ) &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ {
+ OSL_ENSURE( sal_False, "Content::create - unsupported content type!" );
+ return 0;
+ }
+
+#if 0
+ // Fail, if content does exist.
+ if ( Content::hasData( pProvider,
+ Uri( Identifier->getContentIdentifier() ) ) )
+ return 0;
+#endif
+
+ return new Content( rxSMgr, pProvider, Identifier, Info );
+}
+
+//=========================================================================
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
+ ContentProvider * pProvider,
+ const uno::Reference< ucb::XContentIdentifier > & Identifier,
+ const ContentProperties & rProps )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( rProps ),
+ m_eState( PERSISTENT ),
+ m_pProvider( pProvider )
+{
+}
+
+//=========================================================================
+// ctor for a content just created via XContentCreator::createNewContent()
+Content::Content(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( lcl_getContentType( Info.Type ), rtl::OUString() ), // no Title (yet)
+ m_eState( TRANSIENT ),
+ m_pProvider( pProvider )
+{
+}
+
+//=========================================================================
+// 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 = ContentImplHelper::queryInterface( rType );
+
+ if ( !aRet.hasValue() )
+ {
+ aRet = cppu::queryInterface(
+ rType, static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ {
+ if ( !m_aProps.isContentCreator() )
+ return uno::Any();
+ }
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( Content );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( m_aProps.isContentCreator() )
+ {
+ static cppu::OTypeCollection* pFolderTypes = 0;
+
+ pCollection = pFolderTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pFolderTypes;
+ 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 ),
+ CPPU_TYPE_REF( ucb::XContentCreator ) ); // !!
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pFolderTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pDocumentTypes = 0;
+
+ pCollection = pDocumentTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pDocumentTypes;
+ 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;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pDocumentTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.TransientDocumentsContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+
+ if ( m_aProps.getType() == STREAM )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_STREAM_CONTENT_SERVICE_NAME );
+ else if ( m_aProps.getType() == FOLDER )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_FOLDER_CONTENT_SERVICE_NAME );
+ else if ( m_aProps.getType() == DOCUMENT )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_DOCUMENT_CONTENT_SERVICE_NAME );
+ else
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ TDOC_ROOT_CONTENT_SERVICE_NAME );
+
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL Content::getContentType()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return m_aProps.getContentType();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+Content::getIdentifier()
+ throw( uno::RuntimeException )
+{
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Transient?
+ if ( m_eState == TRANSIENT )
+ {
+ // Transient contents have no identifier.
+ return uno::Reference< ucb::XContentIdentifier >();
+ }
+ }
+ return ContentImplHelper::getIdentifier();
+}
+
+//=========================================================================
+//
+// 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 ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= getPropertyValues( Properties );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // setPropertyValues
+ //////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::PropertyValue > aProperties;
+ if ( !( aCommand.Argument >>= aProperties ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ if ( !aProperties.getLength() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "No properties!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= setPropertyValues( aProperties, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getPropertySetInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getPropertySetInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // getCommandInfo
+ //////////////////////////////////////////////////////////////////
+
+ aRet <<= getCommandInfo( Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open
+ //////////////////////////////////////////////////////////////////
+
+ ucb::OpenCommandArgument2 aOpenCommand;
+ if ( !( aCommand.Argument >>= aOpenCommand ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet = open( aOpenCommand, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert ( Supported by folders and streams only )
+ //////////////////////////////////////////////////////////////////
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != STREAM ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "insert command only supported by "
+ "folders and streams!" ) ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ Environment );
+ // Unreachable
+ }
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( eType == STREAM )
+ {
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ Uri aParentUri( aUri.getParentUri() );
+ if ( aParentUri.isDocument() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "insert command not supported by "
+ "streams that are direct children "
+ "of document root!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+#endif
+ ucb::InsertCommandArgument aArg;
+ if ( !( aCommand.Argument >>= aArg ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ sal_Int32 nNameClash = aArg.ReplaceExisting
+ ? ucb::NameClash::OVERWRITE
+ : ucb::NameClash::ERROR;
+ insert( aArg.Data, nNameClash, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete ( Supported by folders and streams only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != STREAM ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "delete command only supported by "
+ "folders and streams!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ sal_Bool bDeletePhysical = sal_False;
+ aCommand.Argument >>= bDeletePhysical;
+ destroy( bDeletePhysical, Environment );
+
+ // Remove own and all children's persistent data.
+ if ( !removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ Environment,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ removeAdditionalPropertySet( sal_True );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer ( Supported by document and folders only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "transfer command only supported "
+ "by folders and documents!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ ucb::TransferInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ transfer( aInfo, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent ( Supported by document and folders only )
+ //////////////////////////////////////////////////////////////////
+
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType != FOLDER ) && ( eType != DOCUMENT ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "createNewContent command only "
+ "supported by folders and "
+ "documents!" ) ),
+ static_cast< cppu::OWeakObject * >(
+ this ) ) ),
+ Environment );
+ // Unreachable
+ }
+ }
+
+ ucb::ContentInfo aInfo;
+ if ( !( aCommand.Argument >>= aInfo ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong argument type!" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Wrong argument type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ Environment );
+ // Unreachable
+ }
+
+ aRet <<= createNewContent( aInfo );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // 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 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+Content::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getCreatableContentsInfo();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+Content::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ if ( m_aProps.isContentCreator() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !Info.Type.getLength() )
+ return uno::Reference< ucb::XContent >();
+
+ sal_Bool bCreateFolder =
+ Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_FOLDER_CONTENT_TYPE ) );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ // streams cannot be created as direct children of document root
+ if ( !bCreateFolder && ( m_aProps.getType() == DOCUMENT ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::createNewContent - streams cannot be "
+ "created as direct children of document root!" );
+ return uno::Reference< ucb::XContent >();
+ }
+#endif
+ if ( !bCreateFolder &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_STREAM_CONTENT_TYPE ) ) )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::createNewContent - unsupported type!" );
+ return uno::Reference< ucb::XContent >();
+ }
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.getLength() > 0,
+ "Content::createNewContent - empty identifier!" );
+
+ if ( ( aURL.lastIndexOf( '/' ) + 1 ) != aURL.getLength() )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ if ( bCreateFolder )
+ aURL += rtl::OUString::createFromAscii( "New_Folder" );
+ else
+ aURL += rtl::OUString::createFromAscii( "New_Stream" );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL );
+
+ return create( m_xSMgr, m_pProvider, xId, Info );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "createNewContent called on non-contentcreator object!" );
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+// virtual
+rtl::OUString Content::getParentURL()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ return aUri.getParentUri();
+}
+
+//=========================================================================
+uno::Reference< ucb::XContentIdentifier >
+Content::makeNewIdentifier( const rtl::OUString& rTitle )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Assemble new content identifier...
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ rtl::OUStringBuffer aNewURL = aUri.getParentUri();
+ aNewURL.append( ::ucb_impl::urihelper::encodeSegment( rTitle ) );
+
+ return
+ uno::Reference< ucb::XContentIdentifier >(
+ new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewURL.makeStringAndClear() ) );
+}
+
+//=========================================================================
+void Content::queryChildren( ContentRefList& rChildren )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Only folders (root, documents, folders) have children.
+ if ( !m_aProps.getIsFolder() )
+ return;
+
+ // 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 nURLPos = aURL.lastIndexOf( '/' );
+
+ if ( nURLPos != ( 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 ) )
+ {
+ sal_Int32 nPos = nLen;
+ nPos = aChildURL.indexOf( '/', nPos );
+
+ 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;
+ }
+}
+
+//=========================================================================
+sal_Bool Content::exchangeIdentity(
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ if ( !xNewId.is() )
+ return sal_False;
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Already persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Only folders and streams can be renamed -> exchange identity.
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( sal_False, "Content::exchangeIdentity - "
+ "Not supported by root or document!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+ if ( !hasData( Uri( xNewId->getContentIdentifier() ) ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ if ( eType == FOLDER )
+ {
+ // Process instanciated children...
+
+ ContentRefList aChildren;
+ queryChildren( aChildren );
+
+ ContentRefList::const_iterator it = aChildren.begin();
+ ContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ ContentRef xChild = (*it);
+
+ // Create new content identifier for the child...
+ uno::Reference< ucb::XContentIdentifier > xOldChildId
+ = xChild->getIdentifier();
+ rtl::OUString aOldChildURL
+ = xOldChildId->getContentIdentifier();
+ rtl::OUString aNewChildURL
+ = aOldChildURL.replaceAt(
+ 0,
+ aOldURL.getLength(),
+ xNewId->getContentIdentifier() );
+ uno::Reference< ucb::XContentIdentifier > xNewChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aNewChildURL );
+
+ if ( !xChild->exchangeIdentity( xNewChildId ) )
+ return sal_False;
+
+ ++it;
+ }
+ }
+ return sal_True;
+ }
+ }
+
+ OSL_ENSURE( sal_False,
+ "Content::exchangeIdentity - "
+ "Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const rtl::OUString& rContentId )
+{
+ ContentProperties aData;
+ if ( loadData( pProvider, rContentId, aData ) )
+ {
+ return getPropertyValues(
+ rSMgr, rProperties, aData, pProvider, rContentId );
+ }
+ else
+ {
+ rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
+ = new ::ucbhelper::PropertyValueSet( rSMgr );
+
+ sal_Int32 nCount = rProperties.getLength();
+ if ( nCount )
+ {
+ const beans::Property* pProps = rProperties.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ xRow->appendVoid( pProps[ n ] );
+ }
+
+ return uno::Reference< sdbc::XRow >( xRow.get() );
+ }
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > Content::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const ContentProperties& rData,
+ ContentProvider* pProvider,
+ 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.getContentType() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ xRow->appendString ( rProp, rData.getTitle() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsDocument() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
+ {
+ xRow->appendBoolean( rProp, rData.getIsFolder() );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
+ {
+ xRow->appendObject(
+ rProp, uno::makeAny( rData.getCreatableContentsInfo() ) );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Storage" ) ) )
+ {
+ // Storage is only supported by folders.
+ ContentType eType = rData.getType();
+ if ( eType == FOLDER )
+ xRow->appendObject(
+ rProp,
+ uno::makeAny(
+ pProvider->queryStorageClone( rContentId ) ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else if ( rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DocumentModel" ) ) )
+ {
+ // DocumentModel is only supported by documents.
+ ContentType eType = rData.getType();
+ if ( eType == DOCUMENT )
+ xRow->appendObject(
+ rProp,
+ uno::makeAny(
+ pProvider->queryDocumentModel( rContentId ) ) );
+ else
+ xRow->appendVoid( rProp );
+ }
+ else
+ {
+ // Not a Core Property! Maybe it's an Additional Core Property?!
+
+ if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
+ {
+ xAdditionalPropSet
+ = uno::Reference< beans::XPropertySet >(
+ pProvider->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.getContentType() );
+
+ ContentType eType = rData.getType();
+
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ // Title is read-only for root and documents.
+ beans::PropertyAttribute::BOUND ||
+ ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ ? beans::PropertyAttribute::READONLY
+ : 0 ),
+ rData.getTitle() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsDocument" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsDocument() );
+ xRow->appendBoolean(
+ beans::Property( rtl::OUString::createFromAscii( "IsFolder" ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ rData.getIsFolder() );
+ xRow->appendObject(
+ beans::Property(
+ rtl::OUString::createFromAscii( "CreatableContentsInfo" ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny( rData.getCreatableContentsInfo() ) );
+
+ // Storage is only supported by folders.
+ if ( eType == FOLDER )
+ xRow->appendObject(
+ beans::Property( rtl::OUString::createFromAscii( "Storage" ),
+ -1,
+ getCppuType(
+ static_cast<
+ const uno::Reference< embed::XStorage > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny( pProvider->queryStorageClone( rContentId ) ) );
+
+ // DocumentModel is only supported by documents.
+ if ( eType == DOCUMENT )
+ xRow->appendObject(
+ beans::Property( rtl::OUString::createFromAscii( "DocumentModel" ),
+ -1,
+ getCppuType(
+ static_cast<
+ const uno::Reference< frame::XModel > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY ),
+ uno::makeAny(
+ pProvider->queryDocumentModel( rContentId ) ) );
+
+ // Append all Additional Core Properties.
+
+ uno::Reference< beans::XPropertySet > xSet(
+ pProvider->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 )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return getPropertyValues( m_xSMgr,
+ rProperties,
+ m_aProps,
+ m_pProvider,
+ m_xIdentifier->getContentIdentifier() );
+}
+
+//=========================================================================
+uno::Sequence< uno::Any > Content::setPropertyValues(
+ const uno::Sequence< beans::PropertyValue >& rValues,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ 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;
+
+ sal_Bool bExchange = sal_False;
+ rtl::OUString aOldTitle;
+ sal_Int32 nTitlePos = -1;
+
+ 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( "CreatableContentsInfo" ) ) )
+ {
+ // 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" ) ) )
+ {
+ // Title is read-only for root and documents.
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty titles!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.getTitle() )
+ {
+ // modified title -> modified URL -> exchange !
+ if ( m_eState == PERSISTENT )
+ bExchange = sal_True;
+
+ aOldTitle = m_aProps.getTitle();
+ m_aProps.setTitle( aNewValue );
+
+ // property change event will be sent later...
+
+ // remember position within sequence of values
+ // (for error handling).
+ nTitlePos = n;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty Title not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Title Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Storage" ) ) )
+ {
+ ContentType eType = m_aProps.getType();
+ if ( eType == FOLDER )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // Storage is only supported by folders.
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "Storage property only supported by folders" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "DocumentModel" ) ) )
+ {
+ ContentType eType = m_aProps.getType();
+ if ( eType == DOCUMENT )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // Storage is only supported by folders.
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "DocumentModel property only supported by "
+ "documents" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ // 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++;
+ }
+ }
+ 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 ( bExchange )
+ {
+ uno::Reference< ucb::XContentIdentifier > xOldId
+ = m_xIdentifier;
+ uno::Reference< ucb::XContentIdentifier > xNewId
+ = makeNewIdentifier( m_aProps.getTitle() );
+
+ aGuard.clear();
+ if ( exchangeIdentity( xNewId ) )
+ {
+ // Adapt persistent data.
+ renameData( xOldId, xNewId );
+
+ // Adapt Additional Core Properties.
+ renameAdditionalPropertySet( xOldId->getContentIdentifier(),
+ xNewId->getContentIdentifier(),
+ sal_True );
+ }
+ else
+ {
+ // Roll-back.
+ m_aProps.setTitle( aOldTitle );
+ aOldTitle = rtl::OUString();
+
+ // Set error .
+ aRet[ nTitlePos ] <<= uno::Exception(
+ rtl::OUString::createFromAscii( "Exchange failed!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+
+ if ( aOldTitle.getLength() )
+ {
+ aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" );
+ aEvent.OldValue = uno::makeAny( aOldTitle );
+ aEvent.NewValue = uno::makeAny( m_aProps.getTitle() );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+ nChanged++;
+ }
+
+ if ( nChanged > 0 )
+ {
+ // Save changes, if content was already made persistent.
+ if ( !bExchange && ( m_eState == PERSISTENT ) )
+ {
+ if ( !storeData( uno::Reference< io::XInputStream >(), xEnv ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+ aChanges.realloc( nChanged );
+
+ aGuard.clear();
+ notifyPropertiesChange( aChanges );
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+uno::Any Content::open(
+ const ucb::OpenCommandArgument2& rArg,
+ const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+ throw( uno::Exception )
+{
+ if ( rArg.Mode == ucb::OpenMode::ALL ||
+ rArg.Mode == ucb::OpenMode::FOLDERS ||
+ rArg.Mode == ucb::OpenMode::DOCUMENTS )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, rArg );
+ return uno::makeAny( xSet );
+ }
+ else
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a document content
+ //////////////////////////////////////////////////////////////////
+
+ if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
+ ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
+ {
+ // Currently(?) unsupported.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedOpenModeException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ sal_Int16( rArg.Mode ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ uno::Reference< io::XActiveDataStreamer > xDataStreamer(
+ rArg.Sink, uno::UNO_QUERY );
+ if ( xDataStreamer.is() )
+ {
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XStream > xStream = getStream( xEnv );
+ if ( !xStream.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference< ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii(
+ "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ // Done.
+ xDataStreamer->setStream( xStream );
+ }
+ else
+ {
+ uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
+ if ( xOut.is() )
+ {
+ // PUSH: write data into xOut
+
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference< ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii( "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
+
+ while ( nRead > 0 )
+ {
+ aBuffer.realloc( nRead );
+ xOut->writeBytes( aBuffer );
+ aBuffer.realloc( 0 );
+ nRead = xIn->readSomeBytes( aBuffer, 65536 );
+ }
+
+ xOut->closeOutput();
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ catch ( io::IOException const & )
+ {
+ // closeOutput, readSomeBytes, writeBytes
+ }
+ }
+ else
+ {
+ uno::Reference< io::XActiveDataSink > xDataSink(
+ rArg.Sink, uno::UNO_QUERY );
+ if ( xDataSink.is() )
+ {
+ // PULL: wait for client read
+
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ uno::Reference< io::XInputStream > xIn = getInputStream( xEnv );
+ if ( !xIn.is() )
+ {
+ // No interaction if we are not persistent!
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ m_eState == PERSISTENT
+ ? xEnv
+ : uno::Reference<
+ ucb::XCommandEnvironment >(),
+ rtl::OUString::createFromAscii(
+ "Got no data stream!" ),
+ this );
+ // Unreachable
+ }
+
+ // Done.
+ xDataSink->setInputStream( xIn );
+ }
+ else
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedDataSinkException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ rArg.Sink ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+ }
+ }
+
+ return uno::Any();
+}
+
+//=========================================================================
+void Content::insert( const uno::Reference< io::XInputStream >& xData,
+ sal_Int32 nNameClashResolve,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+
+ OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
+ "insert command only supported by streams and folders!" );
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+#if OSL_DEBUG_LEVEL > 0
+ if ( eType == STREAM )
+ {
+ Uri aParentUri( aUri.getParentUri() );
+ OSL_ENSURE( !aParentUri.isDocument(),
+ "insert command not supported by streams that are direct "
+ "children of document root!" );
+ }
+#endif
+#endif
+
+ // Check, if all required properties were set.
+ if ( eType == FOLDER )
+ {
+ // Required: Title
+
+ if ( m_aProps.getTitle().getLength() == 0 )
+ m_aProps.setTitle( aUri.getDecodedName() );
+ }
+ else // stream
+ {
+ // Required: data
+
+ if ( !xData.is() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingInputStreamException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Required: Title
+
+ if ( m_aProps.getTitle().getLength() == 0 )
+ m_aProps.setTitle( aUri.getDecodedName() );
+ }
+
+ rtl::OUStringBuffer aNewURL = aUri.getParentUri();
+ aNewURL.append( m_aProps.getTitle() );
+ Uri aNewUri( aNewURL.makeStringAndClear() );
+
+ // Handle possible name clash...
+ switch ( nNameClashResolve )
+ {
+ // fail.
+ case ucb::NameClash::ERROR:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_aProps.getTitle() ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+
+ // replace (possibly) existing object.
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case ucb::NameClash::RENAME:
+ if ( hasData( aNewUri ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ rtl::OUStringBuffer aNew = aNewUri.getUri();
+ aNew.appendAscii( "_" );
+ aNew.append( rtl::OUString::valueOf( ++nTry ) );
+ aNewUri.setUri( aNew.makeStringAndClear() );
+ }
+ while ( hasData( aNewUri ) && ( nTry < 1000 ) );
+
+ if ( nTry == 1000 )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString::createFromAscii(
+ "Unable to resolve name clash!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ else
+ {
+ rtl::OUStringBuffer aNewTitle = m_aProps.getTitle();
+ aNewTitle.appendAscii( "_" );
+ aNewTitle.append( rtl::OUString::valueOf( ++nTry ) );
+ m_aProps.setTitle( aNewTitle.makeStringAndClear() );
+ }
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ default:
+ if ( hasData( aNewUri ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+ }
+
+ // Identifier changed?
+ sal_Bool bNewId = ( aUri != aNewUri );
+
+ if ( bNewId )
+ {
+ m_xIdentifier
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewUri.getUri() );
+ }
+
+ if ( !storeData( xData, xEnv ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny(m_xIdentifier->
+ getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii( "Cannot store persistent data!" ),
+ this );
+ // Unreachable
+ }
+
+ m_eState = PERSISTENT;
+
+ if ( bNewId )
+ {
+ //loadData( m_pProvider, m_aUri, m_aProps );
+
+ aGuard.clear();
+ inserted();
+ }
+}
+
+//=========================================================================
+void Content::destroy( sal_Bool bDeletePhysical,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ // @@@ take care about bDeletePhysical -> trashcan support
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+
+ OSL_ENSURE( ( eType == FOLDER ) || ( eType == STREAM ),
+ "delete command only supported by streams and folders!" );
+
+ uno::Reference< ucb::XContent > xThis = this;
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ m_eState = DEAD;
+
+ aGuard.clear();
+ deleted();
+
+ if ( eType == FOLDER )
+ {
+ // 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, xEnv );
+ ++it;
+ }
+ }
+}
+
+//=========================================================================
+void Content::notifyDocumentClosed()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ m_eState = DEAD;
+
+ // @@@ anything else to reset or such?
+
+ // callback follows!
+ aGuard.clear();
+
+ // Propagate destruction to content event listeners
+ // Remove this from provider's content list.
+ deleted();
+}
+
+//=========================================================================
+uno::Reference< ucb::XContent >
+Content::queryChildContent( const rtl::OUString & rRelativeChildUri )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ const rtl::OUString aMyId = getIdentifier()->getContentIdentifier();
+ rtl::OUStringBuffer aBuf( aMyId );
+ if ( aMyId.getStr()[ aMyId.getLength() - 1 ] != sal_Unicode( '/' ) )
+ aBuf.appendAscii( "/" );
+ if ( rRelativeChildUri.getStr()[ 0 ] != sal_Unicode( '/' ) )
+ aBuf.append( rRelativeChildUri );
+ else
+ aBuf.append( rRelativeChildUri.copy( 1 ) );
+
+ uno::Reference< ucb::XContentIdentifier > xChildId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aBuf.makeStringAndClear() );
+
+ uno::Reference< ucb::XContent > xChild;
+ try
+ {
+ xChild = m_pProvider->queryContent( xChildId );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE( xChild.is(),
+ "Content::queryChildContent - unable to create child content!" );
+ return xChild;
+}
+
+//=========================================================================
+void Content::notifyChildRemoved( const rtl::OUString & rRelativeChildUri )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Ugly! Need to create child content object, just to fill event properly.
+ uno::Reference< ucb::XContent > xChild
+ = queryChildContent( rRelativeChildUri );
+
+ if ( xChild.is() )
+ {
+ // callback follows!
+ aGuard.clear();
+
+ // Notify "REMOVED" event.
+ ucb::ContentEvent aEvt(
+ static_cast< cppu::OWeakObject * >( this ),
+ ucb::ContentAction::REMOVED,
+ xChild,
+ getIdentifier() );
+ notifyContentEvent( aEvt );
+ }
+}
+
+//=========================================================================
+void Content::notifyChildInserted( const rtl::OUString & rRelativeChildUri )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Ugly! Need to create child content object, just to fill event properly.
+ uno::Reference< ucb::XContent > xChild
+ = queryChildContent( rRelativeChildUri );
+
+ if ( xChild.is() )
+ {
+ // callback follows!
+ aGuard.clear();
+
+ // Notify "INSERTED" event.
+ ucb::ContentEvent aEvt(
+ static_cast< cppu::OWeakObject * >( this ),
+ ucb::ContentAction::INSERTED,
+ xChild,
+ getIdentifier() );
+ notifyContentEvent( aEvt );
+ }
+}
+
+//=========================================================================
+void Content::transfer(
+ const ucb::TransferInfo& rInfo,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not persistent!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Does source URI scheme match? Only vnd.sun.star.tdoc is supported.
+
+ if ( ( rInfo.SourceURL.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
+ {
+ // Invaild length (to short).
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ rtl::OUString aScheme
+ = rInfo.SourceURL.copy( 0, TDOC_URL_SCHEME_LENGTH + 2 )
+ .toAsciiLowerCase();
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_URL_SCHEME ":/" ) ) )
+ {
+ // Invalid scheme.
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Does source URI describe a tdoc folder or stream?
+ Uri aSourceUri( rInfo.SourceURL );
+ if ( !aSourceUri.isValid() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! Syntax!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ if ( aSourceUri.isRoot() || aSourceUri.isDocument() )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Must describe a folder or stream!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Is source not a parent of me / not me?
+ rtl::OUString aId = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nPos = aId.lastIndexOf( '/' );
+ if ( nPos != ( aId.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aId += rtl::OUString::createFromAscii( "/" );
+ }
+
+ if ( rInfo.SourceURL.getLength() <= aId.getLength() )
+ {
+ if ( aId.compareTo(
+ rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_RECURSIVE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Target is equal to or is a child of source!" ),
+ this );
+ // Unreachable
+ }
+ }
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( m_aProps.getType() == DOCUMENT )
+ {
+ bool bOK = false;
+
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aSourceUri.getParentUri(), READ_WRITE_NOCREATE );
+ if ( xStorage.is() )
+ {
+ try
+ {
+ if ( xStorage->isStreamElement( aSourceUri.getDecodedName() ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Streams cannot be created as "
+ "children of document root!" ),
+ static_cast< cppu::OWeakObject * >(
+ this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+ bOK = true;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // handled below.
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // handled below.
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // handled below.
+ }
+ }
+
+ if ( !bOK )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Invalid source URI! "
+ "Unabale to determine source type!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 ) ),
+ xEnv );
+ // Unreachable
+ }
+ }
+#endif
+
+ /////////////////////////////////////////////////////////////////////////
+ // Copy data.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aNewName( rInfo.NewTitle.getLength() > 0
+ ? rInfo.NewTitle
+ : aSourceUri.getDecodedName() );
+
+ if ( !copyData( aSourceUri, aNewName ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "Cannot copy data!" ) ),
+ this );
+ // Unreachable
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ // Copy own and all children's Additional Core Properties.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aTargetUri = m_xIdentifier->getContentIdentifier();
+ if ( ( aTargetUri.lastIndexOf( '/' ) + 1 ) != aTargetUri.getLength() )
+ aTargetUri += rtl::OUString::createFromAscii( "/" );
+
+ if ( rInfo.NewTitle.getLength() > 0 )
+ aTargetUri += ::ucb_impl::urihelper::encodeSegment( rInfo.NewTitle );
+ else
+ aTargetUri += aSourceUri.getName();
+
+ if ( !copyAdditionalPropertySet(
+ aSourceUri.getUri(), aTargetUri, sal_True ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Cannot copy additional properties!" ) ),
+ this );
+ // Unreachable
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ // Propagate new content.
+ /////////////////////////////////////////////////////////////////////////
+
+ rtl::Reference< Content > xTarget;
+ try
+ {
+ uno::Reference< ucb::XContentIdentifier > xTargetId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aTargetUri );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the WebDAVContentProvider.
+ xTarget = static_cast< Content * >(
+ m_pProvider->queryContent( xTargetId ).get() );
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( aTargetUri ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate target object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Announce transfered content in its new folder.
+ xTarget->inserted();
+
+ /////////////////////////////////////////////////////////////////////////
+ // Remove source, if requested
+ /////////////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ rtl::Reference< Content > xSource;
+ try
+ {
+ uno::Reference< ucb::XContentIdentifier >
+ xSourceId = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure
+ // that m_xProvider is always the ContentProvider.
+ xSource = static_cast< Content * >(
+ m_xProvider->queryContent( xSourceId ).get() );
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ // queryContent
+ }
+
+ if ( !xSource.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate target object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Propagate destruction (recursively).
+ xSource->destroy( sal_True, xEnv );
+
+ // Remove all persistent data of source and its children.
+ if ( !xSource->removeData() )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove persistent data of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ // Remove own and all children's Additional Core Properties.
+ if ( !xSource->removeAdditionalPropertySet( sal_True ) )
+ {
+ uno::Any aProps
+ = uno::makeAny(
+ beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Uri")),
+ -1,
+ uno::makeAny( rInfo.SourceURL ),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_WRITE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot remove additional properties of source object!" ),
+ this );
+ // Unreachable
+ }
+
+ } // rInfo.MoveData
+}
+
+//=========================================================================
+//static
+bool Content::hasData( ContentProvider* pProvider, const Uri & rUri )
+{
+ if ( rUri.isRoot() )
+ {
+ return true; // root has no storage
+ }
+ else if ( rUri.isDocument() )
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getUri(), READ );
+ return xStorage.is();
+ }
+ else
+ {
+ // folder or stream
+
+ // Ask parent storage. In case that rUri describes a stream,
+ // ContentProvider::queryStorage( rUri ) would return null.
+
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getParentUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ uno::Reference< container::XNameAccess > xParentNA(
+ xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNA.is(), "Got no css.container.XNameAccess!" );
+
+ return xParentNA->hasByName( rUri.getDecodedName() );
+ }
+}
+
+//=========================================================================
+//static
+bool Content::loadData( ContentProvider* pProvider,
+ const Uri & rUri,
+ ContentProperties& rProps )
+{
+ if ( rUri.isRoot() ) // root has no storage, but can always be created
+ {
+ rProps
+ = ContentProperties(
+ ROOT, pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ else if ( rUri.isDocument() ) // document must have storage
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ rProps
+ = ContentProperties(
+ DOCUMENT, pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ else // stream or folder; stream has no storage; folder has storage
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = pProvider->queryStorage( rUri.getParentUri(), READ );
+
+ if ( !xStorage.is() )
+ return false;
+
+ // Check whether exists at all, is stream or folder
+ try
+ {
+ // return: true -> folder
+ // return: false -> stream
+ // NoSuchElementException -> neither folder nor stream
+ bool bIsFolder
+ = xStorage->isStorageElement( rUri.getDecodedName() );
+
+ rProps
+ = ContentProperties(
+ bIsFolder ? FOLDER : STREAM,
+ pProvider->queryStorageTitle( rUri.getUri() ) );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with such name
+ //OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for any reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ }
+ return true;
+}
+
+//=========================================================================
+bool Content::storeData( const uno::Reference< io::XInputStream >& xData,
+ const uno::Reference<
+ ucb::XCommandEnvironment >& xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "storeData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+
+ if ( eType == FOLDER )
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage( aUri.getUri(), READ_WRITE_CREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ xStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xPropSet.is(),
+ "Content::storeData - Got no XPropertySet interface!" );
+ if ( !xPropSet.is() )
+ return false;
+
+ try
+ {
+ // According to MBA, if no mediatype is set, folder and all
+ // its contents will be lost on save of the document!!!
+ xPropSet->setPropertyValue(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
+ uno::makeAny(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ // @@@ better mediatype
+ "application/binary" ) ) ) );
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ OSL_ENSURE( false, "Property MediaType not supported!" );
+ return false;
+ }
+ catch ( beans::PropertyVetoException const & )
+ {
+ OSL_ENSURE( false, "Caught PropertyVetoException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ return false;
+ }
+
+ if ( !commitStorage( xStorage ) )
+ return false;
+ }
+ else if ( eType == STREAM )
+ {
+ // stream
+
+ // Important: Parent storage and output stream must be kept alive until
+ // changes have been committed!
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aUri.getParentUri(), READ_WRITE_CREATE );
+ uno::Reference< io::XOutputStream > xOut;
+
+ if ( !xStorage.is() )
+ return false;
+
+ if ( xData.is() )
+ {
+ // May throw CommandFailedException, DocumentPasswordRequest!
+ xOut = getTruncatedOutputStream( xEnv );
+
+ OSL_ENSURE( xOut.is(), "No target data stream!" );
+
+ try
+ {
+ uno::Sequence< sal_Int8 > aBuffer;
+ sal_Int32 nRead = xData->readSomeBytes( aBuffer, 65536 );
+
+ while ( nRead > 0 )
+ {
+ aBuffer.realloc( nRead );
+ xOut->writeBytes( aBuffer );
+ aBuffer.realloc( 0 );
+ nRead = xData->readSomeBytes( aBuffer, 65536 );
+ }
+
+ closeOutputStream( xOut );
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught NotConnectedException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught BufferSizeExceededException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // readSomeBytes, writeBytes
+ OSL_ENSURE( false, "Caught IOException!" );
+ closeOutputStream( xOut );
+ return false;
+ }
+ catch ( ... )
+ {
+ closeOutputStream( xOut );
+ throw;
+ }
+ }
+
+ // Commit changes.
+ if ( !commitStorage( xStorage ) )
+ return false;
+ }
+ else
+ {
+ OSL_ENSURE( false, "Unknown content type!" );
+ return false;
+ }
+ return true;
+}
+
+//=========================================================================
+bool Content::renameData(
+ const uno::Reference< ucb::XContentIdentifier >& xOldId,
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "renameData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aOldUri( xOldId->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aOldUri.getParentUri(), READ_WRITE_NOCREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ try
+ {
+ Uri aNewUri( xNewId->getContentIdentifier() );
+ xStorage->renameElement(
+ aOldUri.getDecodedName(), aNewUri.getDecodedName() );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with old name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // an element with new name already exists in this storage
+ OSL_ENSURE( false, "Caught ElementExistException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xStorage );
+}
+
+//=========================================================================
+bool Content::removeData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == DOCUMENT ) )
+ {
+ OSL_ENSURE( false, "removeData not supported by root and documents!" );
+ return false;
+ }
+
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xStorage
+ = m_pProvider->queryStorage(
+ aUri.getParentUri(), READ_WRITE_NOCREATE );
+
+ if ( !xStorage.is() )
+ return false;
+
+ try
+ {
+ xStorage->removeElement( aUri.getDecodedName() );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xStorage );
+}
+
+//=========================================================================
+bool Content::copyData( const Uri & rSourceUri, const rtl::OUString & rNewName )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ ContentType eType = m_aProps.getType();
+ if ( ( eType == ROOT ) || ( eType == STREAM ) )
+ {
+ OSL_ENSURE( false, "copyData not supported by root and streams!" );
+ return false;
+ }
+
+ Uri aDestUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< embed::XStorage > xDestStorage
+ = m_pProvider->queryStorage( aDestUri.getUri(), READ_WRITE_NOCREATE );
+
+ if ( !xDestStorage.is() )
+ return false;
+
+ uno::Reference< embed::XStorage > xSourceStorage
+ = m_pProvider->queryStorage( rSourceUri.getParentUri(), READ );
+
+ if ( !xSourceStorage.is() )
+ return false;
+
+ try
+ {
+ xSourceStorage->copyElementTo( rSourceUri.getDecodedName(),
+ xDestStorage,
+ rNewName );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ // this storage is in invalid state for eny reason
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ return false;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // an illegal argument is provided
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ return false;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught NoSuchElementException!" );
+ return false;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // there is no element with this name in this storage
+ OSL_ENSURE( false, "Caught ElementExistException!" );
+ return false;
+ }
+ catch ( io::IOException const & )
+ {
+ // in case of io errors during renaming
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ // wraps other exceptions
+ OSL_ENSURE( false, "Caught StorageWrappedTargetException!" );
+ return false;
+ }
+
+ return commitStorage( xDestStorage );
+}
+
+//=========================================================================
+// static
+bool Content::commitStorage( const uno::Reference< embed::XStorage > & xStorage )
+{
+ // Commit changes
+ uno::Reference< embed::XTransactedObject > xTO( xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xTO.is(),
+ "Required interface css.embed.XTransactedObject missing!" );
+ try
+ {
+ xTO->commit();
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ return false;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ return false;
+ }
+
+ return true;
+}
+
+//=========================================================================
+// static
+bool Content::closeOutputStream(
+ const uno::Reference< io::XOutputStream > & xOut )
+{
+ if ( xOut.is() )
+ {
+ try
+ {
+ xOut->closeOutput();
+ return true;
+ }
+ catch ( io::NotConnectedException const & )
+ {
+ OSL_ENSURE( false, "Caught NotConnectedException!" );
+ }
+ catch ( io::BufferSizeExceededException const & )
+ {
+ OSL_ENSURE( false, "Caught BufferSizeExceededException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ }
+ }
+ return false;
+}
+
+//=========================================================================
+static rtl::OUString obtainPassword(
+ const rtl::OUString & rName,
+ task::PasswordRequestMode eMode,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::Reference< DocumentPasswordRequest > xRequest
+ = new DocumentPasswordRequest( eMode, rName );
+
+ if ( xEnv.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = xEnv->getInteractionHandler();
+ if ( xIH.is() )
+ {
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ throw ucb::CommandFailedException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Abort requested by Interaction Handler." ) ),
+ uno::Reference< uno::XInterface >(),
+ xRequest->getRequest() );
+ }
+
+ uno::Reference< task::XInteractionPassword > xPassword(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xPassword.is() )
+ {
+ return xPassword->getPassword();
+ }
+
+ // Unknown selection. Should never happen.
+ throw ucb::CommandFailedException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Interaction Handler selected unknown continuation!" ) ),
+ uno::Reference< uno::XInterface >(),
+ xRequest->getRequest() );
+ }
+ }
+ }
+
+ // No IH or IH did not handle exception.
+ task::DocumentPasswordRequest aRequest;
+ xRequest->getRequest() >>= aRequest;
+ throw aRequest;
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream > Content::getInputStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::OUString aUri;
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getInputStream - content is no stream!" );
+
+ aUri = Uri( m_xIdentifier->getContentIdentifier() ).getUri();
+ }
+
+ for ( ;; )
+ {
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ return uno::Reference< io::XInputStream >(
+ m_pProvider->queryInputStream( aUri, aPassword ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( aUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+static uno::Reference< io::XOutputStream > lcl_getTruncatedOutputStream(
+ const rtl::OUString & rUri,
+ ContentProvider * pProvider,
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+ for ( ;; )
+ {
+ try
+ {
+ return uno::Reference< io::XOutputStream >(
+ pProvider->queryOutputStream(
+ rUri, aPassword, true /* truncate */ ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( rUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream > Content::getTruncatedOutputStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getTruncatedOutputStream - content is no stream!" );
+
+ return lcl_getTruncatedOutputStream(
+ Uri( m_xIdentifier->getContentIdentifier() ).getUri(),
+ m_pProvider,
+ xEnv );
+}
+
+//=========================================================================
+uno::Reference< io::XStream > Content::getStream(
+ const uno::Reference< ucb::XCommandEnvironment > & xEnv )
+ throw ( ucb::CommandFailedException,
+ task::DocumentPasswordRequest )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ OSL_ENSURE( m_aProps.getType() == STREAM,
+ "Content::getStream - content is no stream!" );
+
+ rtl::OUString aUri( Uri( m_xIdentifier->getContentIdentifier() ).getUri() );
+ rtl::OUString aPassword;
+ bool bPasswordRequested = false;
+ for ( ;; )
+ {
+ try
+ {
+ return uno::Reference< io::XStream >(
+ m_pProvider->queryStream(
+ aUri, aPassword, false /* no truncate */ ) );
+ }
+ catch ( packages::WrongPasswordException const & )
+ {
+ // Obtain (new) password.
+ aPassword
+ = obtainPassword( aUri, /* @@@ find better title */
+ bPasswordRequested
+ ? task::PasswordRequestMode_PASSWORD_REENTER
+ : task::PasswordRequestMode_PASSWORD_ENTER,
+ xEnv );
+ bPasswordRequested = true;
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+uno::Sequence< ucb::ContentInfo >
+ContentProperties::getCreatableContentsInfo() const
+{
+ if ( isContentCreator() )
+ {
+ uno::Sequence< beans::Property > aProps( 1 );
+ aProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ if ( getType() == DOCUMENT )
+ {
+ // streams cannot be created as direct children of document root
+ uno::Sequence< ucb::ContentInfo > aSeq( 1 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+ aSeq.getArray()[ 0 ].Properties = aProps;
+
+ return aSeq;
+ }
+ else
+ {
+#endif
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+ aSeq.getArray()[ 0 ].Properties = aProps;
+
+ // Stream.
+ aSeq.getArray()[ 1 ].Type
+ = rtl::OUString::createFromAscii( TDOC_STREAM_CONTENT_TYPE );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
+ | ucb::ContentInfoAttribute::KIND_DOCUMENT;
+ aSeq.getArray()[ 1 ].Properties = aProps;
+
+ return aSeq;
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ }
+#endif
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "getCreatableContentsInfo called on non-contentcreator "
+ "object!" );
+
+ return uno::Sequence< ucb::ContentInfo >( 0 );
+ }
+}
+
+//=========================================================================
+bool ContentProperties::isContentCreator() const
+{
+ return ( getType() == FOLDER ) || ( getType() == DOCUMENT );
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_content.hxx b/ucb/source/ucp/tdoc/tdoc_content.hxx
new file mode 100644
index 000000000000..b3a3270292be
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_content.hxx
@@ -0,0 +1,342 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_CONTENT_HXX
+#define INCLUDED_TDOC_CONTENT_HXX
+
+#include <ucbhelper/contenthelper.hxx>
+#include <com/sun/star/task/DocumentPasswordRequest.hpp>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+#include "tdoc_provider.hxx"
+
+#define NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT 1
+
+namespace com { namespace sun { namespace star {
+ namespace sdbc { class XRow; }
+ namespace io { class XInputStream; class XOutputStream; }
+ namespace beans { struct PropertyValue; }
+ namespace ucb { struct OpenCommandArgument2; struct TransferInfo;
+ struct ContentInfo; }
+} } }
+
+namespace tdoc_ucp
+{
+
+//=========================================================================
+
+#define TDOC_ROOT_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsRootContent"
+#define TDOC_DOCUMENT_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsDocumentContent"
+#define TDOC_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsFolderContent"
+#define TDOC_STREAM_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsStreamContent"
+
+//=========================================================================
+
+enum ContentType { STREAM, FOLDER, DOCUMENT, ROOT };
+
+class ContentProperties
+{
+public:
+ ContentProperties()
+ {}
+
+ ContentProperties( const ContentType & rType, const rtl::OUString & rTitle )
+ : m_eType( rType ),
+ m_aContentType( rType == STREAM
+ ? rtl::OUString::createFromAscii( TDOC_STREAM_CONTENT_TYPE )
+ : rType == FOLDER
+ ? rtl::OUString::createFromAscii( TDOC_FOLDER_CONTENT_TYPE )
+ : rType == DOCUMENT
+ ? rtl::OUString::createFromAscii( TDOC_DOCUMENT_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( TDOC_ROOT_CONTENT_TYPE ) ),
+ m_aTitle( rTitle )
+ {}
+
+ ContentType getType() const { return m_eType; }
+
+ // Properties
+
+ const rtl::OUString & getContentType() const { return m_aContentType; }
+
+ bool getIsFolder() const { return m_eType > STREAM; }
+ bool getIsDocument() const { return !getIsFolder(); }
+
+ const rtl::OUString & getTitle() const { return m_aTitle; }
+ void setTitle( const rtl::OUString & rTitle ) { m_aTitle = rTitle; }
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ getCreatableContentsInfo() const;
+
+ bool isContentCreator() const;
+
+private:
+ ContentType m_eType;
+ rtl::OUString m_aContentType;
+ rtl::OUString m_aTitle;
+};
+
+//=========================================================================
+
+class Content : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ContentState { TRANSIENT, // created via createNewContent,
+ // but did not process "insert" yet
+ PERSISTENT, // processed "insert"
+ DEAD // processed "delete" / document was closed
+ };
+
+ ContentProperties m_aProps;
+ ContentState m_eState;
+ ContentProvider* m_pProvider;
+
+private:
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const ContentProperties & rProps );
+ Content( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
+ getProperties( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
+ getCommands( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment > & xEnv );
+ virtual ::rtl::OUString getParentURL();
+
+ static bool hasData( ContentProvider* pProvider, const Uri & rUri );
+ bool hasData( const Uri & rUri ) { return hasData( m_pProvider, rUri ); }
+
+ static bool loadData( ContentProvider* pProvider,
+ const Uri & rUri,
+ ContentProperties& rProps );
+ bool storeData( const com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream >& xData,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+ bool renameData( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xOldId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& xNewId );
+ bool removeData();
+
+ bool copyData( const Uri & rSourceUri, const rtl::OUString & rNewName );
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >
+ makeNewIdentifier( const rtl::OUString& rTitle );
+
+ typedef rtl::Reference< Content > ContentRef;
+ typedef std::list< ContentRef > ContentRefList;
+ void queryChildren( ContentRefList& rChildren );
+
+ sal_Bool exchangeIdentity(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >& xNewId );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
+ setPropertyValues(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& rValues,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ com::sun::star::uno::Any
+ open( const ::com::sun::star::ucb::OpenCommandArgument2& rArg,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void insert( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream >& xData,
+ sal_Int32 nNameClashResolve,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void destroy( sal_Bool bDeletePhysical,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ void transfer( const ::com::sun::star::ucb::TransferInfo& rInfo,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw( ::com::sun::star::uno::Exception );
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ const ContentProperties& rData,
+ ContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+
+
+ static bool commitStorage(
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStorage );
+
+ static bool closeOutputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & xOut );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+ getInputStream( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > &
+ xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ getTruncatedOutputStream(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent >
+ queryChildContent( const rtl::OUString & rRelativeChildUri );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >
+ getStream( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XCommandEnvironment > & xEnv )
+ throw ( ::com::sun::star::ucb::CommandFailedException,
+ ::com::sun::star::task::DocumentPasswordRequest );
+
+public:
+ // Create existing content. Fail, if not already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ // Create new content. Fail, if already exists.
+ static Content* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ ContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual ~Content();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XContent
+ virtual rtl::OUString SAL_CALL
+ getContentType()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ getIdentifier()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XCommandProcessor
+ virtual com::sun::star::uno::Any SAL_CALL
+ execute( const com::sun::star::ucb::Command& aCommand,
+ sal_Int32 CommandId,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XCommandEnvironment >& Environment )
+ throw( com::sun::star::uno::Exception,
+ com::sun::star::ucb::CommandAbortedException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ abort( sal_Int32 CommandId )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Additional interfaces
+ //////////////////////////////////////////////////////////////////////
+
+ // XContentCreator
+ virtual com::sun::star::uno::Sequence<
+ com::sun::star::ucb::ContentInfo > SAL_CALL
+ queryCreatableContentsInfo()
+ throw( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createNewContent( const com::sun::star::ucb::ContentInfo& Info )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //////////////////////////////////////////////////////////////////////
+ // Non-interface methods.
+ //////////////////////////////////////////////////////////////////////
+
+ static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
+ getPropertyValues( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::Property >& rProperties,
+ ContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+
+ void notifyDocumentClosed();
+ void notifyChildRemoved( const rtl::OUString & rRelativeChildUri );
+ void notifyChildInserted( const rtl::OUString & rRelativeChildUri );
+
+ rtl::Reference< ContentProvider > getContentProvider() const
+ { return rtl::Reference< ContentProvider >( m_pProvider ); }
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_CONTENT_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
new file mode 100644
index 000000000000..d8c89c351c89
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_contentcaps.cxx
@@ -0,0 +1,705 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ **************************************************************************
+
+ Props/Commands:
+
+ root document folder folder stream stream
+ (new) (new)
+ ----------------------------------------------------------------
+ ContentType r r r r r r
+ IsDocument r r r r r r
+ IsFolder r r r r r r
+ Title r r w w w w
+ CreatableContentsInfo r r r r r r
+ Storage - - r r - -
+ DocumentModel - r - - - -
+
+ getCommandInfo x x x x x x
+ getPropertySetInfo x x x x x x
+ getPropertyValues x x x x x x
+ setPropertyValues x x x x x x
+ insert - - x x x(*) x(*)
+ delete - - x - x -
+ open x x x - x -
+ transfer - x x - - -
+ createNewContent - x x - - -
+
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ (*) not supported by streams that are direct children of document
+#endif
+
+ *************************************************************************/
+
+#include "com/sun/star/beans/Property.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/ucb/CommandInfo.hpp"
+#include "com/sun/star/ucb/OpenCommandArgument2.hpp"
+#include "com/sun/star/ucb/TransferInfo.hpp"
+
+#include "tdoc_content.hxx"
+
+namespace com { namespace sun { namespace star { namespace embed {
+ class XStorage;
+} } } }
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//
+// Content implementation.
+//
+//=========================================================================
+
+#define MAKEPROPSEQUENCE( a ) \
+ uno::Sequence< beans::Property >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+#define MAKECMDSEQUENCE( a ) \
+ uno::Sequence< ucb::CommandInfo >( a, sizeof( a ) / sizeof( a[ 0 ] ) )
+
+//=========================================================================
+//
+// IMPORTENT: If any property data ( name / type / ... ) are changed, then
+// Content::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > Content::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_aProps.getType() == STREAM )
+ {
+ //=================================================================
+ //
+ // Stream: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aStreamPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aStreamPropertyInfoTable );
+ }
+ else if ( m_aProps.getType() == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Storage" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Reference< embed::XStorage > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+ return MAKEPROPSEQUENCE( aFolderPropertyInfoTable );
+ }
+ else if ( m_aProps.getType() == DOCUMENT )
+ {
+ //=================================================================
+ //
+ // Document: Supported properties
+ //
+ //=================================================================
+
+ static const beans::Property aDocPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentModel" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Reference< frame::XModel > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ };
+ return MAKEPROPSEQUENCE( aDocPropertyInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root: Supported properties
+ //
+ //=================================================================
+
+ OSL_ENSURE( m_aProps.getType() == ROOT, "Wrong content type!" );
+
+ static const beans::Property aRootPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Mandatory properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
+ -1,
+ getCppuBooleanType(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ ///////////////////////////////////////////////////////////////
+ // Optional standard properties
+ ///////////////////////////////////////////////////////////////
+ beans::Property(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "CreatableContentsInfo" ) ),
+ -1,
+ getCppuType( static_cast<
+ const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ )
+ ///////////////////////////////////////////////////////////////
+ // New properties
+ ///////////////////////////////////////////////////////////////
+ };
+ return MAKEPROPSEQUENCE( aRootPropertyInfoTable );
+ }
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > Content::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_aProps.getType() == STREAM )
+ {
+#ifdef NO_STREAM_CREATION_WITHIN_DOCUMENT_ROOT
+ Uri aUri( m_xIdentifier->getContentIdentifier() );
+ Uri aParentUri( aUri.getParentUri() );
+
+ if ( aParentUri.isDocument() )
+ {
+ //=================================================================
+ //
+ // Stream, that is a child of a document: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aStreamCommandInfoTable1[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aStreamCommandInfoTable1 );
+ }
+#endif
+ //=================================================================
+ //
+ // Stream: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aStreamCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aStreamCommandInfoTable );
+ }
+ else if ( m_aProps.getType() == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
+ -1,
+ getCppuBooleanType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aFolderCommandInfoTable );
+ }
+ else if ( m_aProps.getType() == DOCUMENT )
+ {
+ //=================================================================
+ //
+ // Document: Supported commands
+ //
+ //=================================================================
+
+ static const ucb::CommandInfo aDocCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
+ -1,
+ getCppuType( static_cast< ucb::TransferInfo * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
+ -1,
+ getCppuType( static_cast< ucb::ContentInfo * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aDocCommandInfoTable );
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root: Supported commands
+ //
+ //=================================================================
+
+ OSL_ENSURE( m_aProps.getType() == ROOT, "Wrong content type!" );
+
+ static const ucb::CommandInfo aRootCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Mandatory commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
+ -1,
+ getCppuVoidType()
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast< uno::Sequence< beans::Property > * >( 0 ) )
+ ),
+ ucb::CommandInfo(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
+ -1,
+ getCppuType(
+ static_cast<
+ uno::Sequence< beans::PropertyValue > * >( 0 ) )
+ ),
+ ///////////////////////////////////////////////////////////
+ // Optional standard commands
+ ///////////////////////////////////////////////////////////
+ ucb::CommandInfo(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
+ -1,
+ getCppuType(
+ static_cast< ucb::OpenCommandArgument2 * >( 0 ) )
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aRootCommandInfoTable );
+ }
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx b/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx
new file mode 100644
index 000000000000..c9931c872b16
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_datasupplier.cxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include <vector>
+
+#include "osl/diagnose.h"
+#include "ucbhelper/contentidentifier.hxx"
+
+#include "tdoc_datasupplier.hxx"
+#include "tdoc_content.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+namespace tdoc_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aURL;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+
+ ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< Content > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ uno::Sequence< rtl::OUString > * m_pNamesOfChildren;
+ sal_Int32 m_nOpenMode;
+ bool m_bCountFinal;
+ bool m_bThrowException;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_pNamesOfChildren( 0 ), m_nOpenMode( nOpenMode ),
+ m_bCountFinal( false ), m_bThrowException( false )
+ {}
+ ~DataSupplier_Impl();
+};
+
+//=========================================================================
+DataSupplier_Impl::~DataSupplier_Impl()
+{
+ ResultList::const_iterator it = m_aResults.begin();
+ ResultList::const_iterator end = m_aResults.end();
+
+ while ( it != end )
+ {
+ delete (*it);
+ it++;
+ }
+
+ delete m_pNamesOfChildren;
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ResultSetDataSupplier::ResultSetDataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+ResultSetDataSupplier::~ResultSetDataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString
+ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
+ return m_pImpl->m_aResults[ nIndex ]->aURL;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = m_pImpl->m_aResults[ nIndex ]->xId;
+ if ( xId.is() )
+ {
+ // Already cached.
+ return xId;
+ }
+ }
+
+ rtl::OUString aId = queryContentIdentifierString( nIndex );
+ if ( aId.getLength() )
+ {
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( aId );
+ m_pImpl->m_aResults[ nIndex ]->xId = xId;
+ return xId;
+ }
+ return uno::Reference< ucb::XContentIdentifier >();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent >
+ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_aResults[ nIndex ]->xContent;
+ if ( xContent.is() )
+ {
+ // Already cached.
+ return xContent;
+ }
+ }
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = queryContentIdentifier( nIndex );
+ if ( xId.is() )
+ {
+ try
+ {
+ uno::Reference< ucb::XContent > xContent
+ = m_pImpl->m_xContent->getProvider()->queryContent( xId );
+ m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
+ return xContent;
+
+ }
+ catch ( ucb::IllegalIdentifierException const & )
+ {
+ }
+ }
+ return uno::Reference< ucb::XContent >();
+}
+
+//=========================================================================
+// virtual
+sal_Bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_aResults.size() > nIndex )
+ {
+ // Result already present.
+ return sal_True;
+ }
+
+ // Result not (yet) present.
+
+ if ( m_pImpl->m_bCountFinal )
+ return sal_False;
+
+ // Try to obtain result...
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+ bool bFound = false;
+
+ if ( queryNamesOfChildren() )
+ {
+ for ( sal_uInt32 n = nOldCount;
+ n < sal::static_int_cast<sal_uInt32>(
+ m_pImpl->m_pNamesOfChildren->getLength());
+ ++n )
+ {
+ const rtl::OUString & rName
+ = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
+
+ if ( !rName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "ResultDataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( rName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+
+ if ( n == nIndex )
+ {
+ // Result obtained.
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if ( !bFound )
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
+
+ if ( m_pImpl->m_bCountFinal )
+ xResultSet->rowCountFinal();
+ }
+
+ return bFound;
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 ResultSetDataSupplier::totalCount()
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_bCountFinal )
+ return m_pImpl->m_aResults.size();
+
+ sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
+
+ if ( queryNamesOfChildren() )
+ {
+ for ( sal_uInt32 n = nOldCount;
+ n < sal::static_int_cast<sal_uInt32>(
+ m_pImpl->m_pNamesOfChildren->getLength());
+ ++n )
+ {
+ const rtl::OUString & rName
+ = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
+
+ if ( !rName.getLength() )
+ {
+ OSL_ENSURE( sal_False,
+ "ResultDataSupplier::getResult - Empty name!" );
+ break;
+ }
+
+ // Assemble URL for child.
+ rtl::OUString aURL = assembleChildURL( rName );
+
+ m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
+ }
+ }
+
+ m_pImpl->m_bCountFinal = sal_True;
+
+ rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
+ if ( xResultSet.is() )
+ {
+ // Callbacks follow!
+ aGuard.clear();
+
+ if ( nOldCount < m_pImpl->m_aResults.size() )
+ xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
+
+ xResultSet->rowCountFinal();
+ }
+
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_uInt32 ResultSetDataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool ResultSetDataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow >
+ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ {
+ uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
+ if ( xRow.is() )
+ {
+ // Already cached.
+ return xRow;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ m_pImpl->m_xContent->getContentProvider().get(),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( nIndex < m_pImpl->m_aResults.size() )
+ m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void ResultSetDataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+ if ( m_pImpl->m_bThrowException )
+ throw ucb::ResultSetException();
+}
+
+//=========================================================================
+bool ResultSetDataSupplier::queryNamesOfChildren()
+{
+ osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
+
+ if ( m_pImpl->m_pNamesOfChildren == 0 )
+ {
+ uno::Sequence< rtl::OUString > * pNamesOfChildren
+ = new uno::Sequence< rtl::OUString >();
+
+ if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
+ m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
+ *pNamesOfChildren ) )
+ {
+ OSL_ENSURE( false, "Got no list of children!" );
+ m_pImpl->m_bThrowException = sal_True;
+ return false;
+ }
+ else
+ {
+ m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
+ }
+ }
+ return true;
+}
+
+//=========================================================================
+::rtl::OUString
+ResultSetDataSupplier::assembleChildURL( const ::rtl::OUString& aName )
+{
+ rtl::OUString aContURL
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+ rtl::OUString aURL( aContURL );
+
+ sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
+ if ( nUrlEnd != aURL.getLength() - 1 )
+ aURL += rtl::OUString::createFromAscii( "/" );
+
+ aURL += aName;
+ return aURL;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx b/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx
new file mode 100644
index 000000000000..28d9a4eba9a2
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_datasupplier.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DATASUPPLIER_HXX
+#define INCLUDED_TDOC_DATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/resultset.hxx>
+
+namespace tdoc_ucp {
+
+struct DataSupplier_Impl;
+class Content;
+
+class ResultSetDataSupplier : public ::ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+private:
+ bool queryNamesOfChildren();
+ ::rtl::OUString assembleChildURL( const ::rtl::OUString& aName );
+
+public:
+ ResultSetDataSupplier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rContent,
+ sal_Int32 nOpenMode = com::sun::star::ucb::OpenMode::ALL );
+ virtual ~ResultSetDataSupplier();
+
+ virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >
+ queryContentIdentifier( sal_uInt32 nIndex );
+ virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+ queryContent( sal_uInt32 nIndex );
+
+ virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+ virtual sal_uInt32 totalCount();
+ virtual sal_uInt32 currentCount();
+ virtual sal_Bool isCountFinal();
+
+ virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+ queryPropertyValues( sal_uInt32 nIndex );
+ virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+ virtual void close();
+
+ virtual void validate()
+ throw( com::sun::star::ucb::ResultSetException );
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DATASUPPLIER_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.cxx b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
new file mode 100644
index 000000000000..46aa1ae69ec3
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.cxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - filter unwanted models notified by global document event broadcaster
+ - help documents
+ - others, which I don't know yet
+
+ *************************************************************************/
+
+#include "osl/diagnose.h"
+#include "rtl/ref.hxx"
+#include "cppuhelper/weak.hxx"
+
+#include "comphelper/namedvaluecollection.hxx"
+#include "comphelper/documentinfo.hxx"
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/container/XEnumerationAccess.hpp"
+#include "com/sun/star/frame/XStorable.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/document/XStorageBasedDocument.hpp"
+#include "com/sun/star/awt/XTopWindow.hpp"
+
+#include "tdoc_docmgr.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+using ::comphelper::DocumentInfo;
+
+//=========================================================================
+//=========================================================================
+//
+// OfficeDocumentsManager Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+OfficeDocumentsManager::OfficeDocumentsManager(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ OfficeDocumentsEventListener * pDocEventListener )
+: m_xSMgr( xSMgr ),
+ m_xDocEvtNotifier( createDocumentEventNotifier( xSMgr ) ),
+ m_pDocEventListener( pDocEventListener )
+{
+ if ( m_xDocEvtNotifier.is() )
+ {
+ // Order is important (multithreaded environment)
+ m_xDocEvtNotifier->addEventListener( this );
+ buildDocumentsList();
+ }
+}
+
+//=========================================================================
+// virtual
+OfficeDocumentsManager::~OfficeDocumentsManager()
+{
+ OSL_ENSURE( m_aDocs.empty(), "document list not empty!" );
+}
+
+//=========================================================================
+void OfficeDocumentsManager::destroy()
+{
+ if ( m_xDocEvtNotifier.is() )
+ m_xDocEvtNotifier->removeEventListener( this );
+}
+
+//=========================================================================
+static rtl::OUString
+getDocumentId( const uno::Reference< uno::XInterface > & xDoc )
+{
+ rtl::OUString aId;
+
+ // Try to get the UID directly from the document.
+ uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ uno::Any aValue = xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "RuntimeUID" ) ) );
+ aValue >>= aId;
+ }
+ catch ( beans::UnknownPropertyException const & )
+ {
+ // Not actually an error. Property is optional.
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+ }
+ }
+
+ if ( aId.getLength() == 0 )
+ {
+ // fallback: generate UID from document's this pointer.
+ // normalize the interface pointer first. Else, calls with different
+ // interfaces to the same object (say, XFoo and XBar) will produce
+ // different IDs
+ uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY );
+ sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() );
+ aId = rtl::OUString::valueOf( nId );
+ }
+
+ OSL_ENSURE( aId.getLength() > 0, "getDocumentId - Empty id!" );
+ return aId;
+}
+
+//=========================================================================
+//
+// document::XEventListener
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL OfficeDocumentsManager::notifyEvent(
+ const document::EventObject & Event )
+ throw ( uno::RuntimeException )
+{
+/*
+ Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs
+*/
+
+ if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnLoadFinished" ) ) // document loaded
+ || Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnCreate" ) ) ) // document created
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // already known.
+ break;
+ }
+ ++it;
+ }
+
+ if ( it == m_aDocs.end() )
+ {
+ // new document
+
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ rtl:: OUString aDocId = getDocumentId( Event.Source );
+ rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+
+ m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
+
+ // Propagate document closure.
+ OSL_ENSURE( m_pDocEventListener,
+ "OnLoadFinished/OnCreate event: no owner for insert event propagation!" );
+
+ if ( m_pDocEventListener )
+ m_pDocEventListener->notifyDocumentOpened( aDocId );
+ }
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnUnload" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ // Document has been closed (unloaded)
+
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Propagate document closure.
+ OSL_ENSURE( m_pDocEventListener,
+ "OnUnload event: no owner for close event propagation!" );
+
+ if ( m_pDocEventListener )
+ {
+ rtl::OUString aDocId( (*it).first );
+ m_pDocEventListener->notifyDocumentClosed( aDocId );
+ }
+
+
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnUnload event notified for unknown document!" );
+
+ if( it != m_aDocs.end() )
+ m_aDocs.erase( it );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnSaveDone" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Storage gets exchanged while saving.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ (*it).second.xStorage = xStorage;
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnSaveDone event notified for unknown document!" );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnSaveAsDone" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Storage gets exchanged while saving.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xStorage.is(), "Got no document storage!" );
+
+ (*it).second.xStorage = xStorage;
+
+ // Adjust title.
+ (*it).second.aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "OnSaveAsDone event notified for unknown document!" );
+ }
+ }
+ else if ( Event.EventName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "OnTitleChanged" ) ) )
+ {
+ if ( isOfficeDocument( Event.Source ) )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Reference< frame::XModel >
+ xModel( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xModel.is(), "Got no frame::XModel!" );
+
+ DocumentList::iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // Adjust title.
+ rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) );
+ (*it).second.aTitle = aTitle;
+
+ // Adjust storage.
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( Event.Source, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xDoc.is(), "Got no document storage!" );
+
+ rtl:: OUString aDocId = getDocumentId( Event.Source );
+
+ m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel );
+ break;
+ }
+ ++it;
+ }
+
+ OSL_ENSURE( it != m_aDocs.end(),
+ "TitleChanged event notified for unknown document!" );
+ }
+ }
+}
+
+//=========================================================================
+//
+// lang::XEventListener (base of document::XEventListener)
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL OfficeDocumentsManager::disposing(
+ const lang::EventObject& /*Source*/ )
+ throw ( uno::RuntimeException )
+{
+}
+
+//=========================================================================
+//
+// Non-interface.
+//
+//=========================================================================
+
+// static
+uno::Reference< document::XEventBroadcaster >
+OfficeDocumentsManager::createDocumentEventNotifier(
+ const uno::Reference< lang::XMultiServiceFactory >& rXSMgr )
+{
+ uno::Reference< uno::XInterface > xIfc;
+ try
+ {
+ xIfc = rXSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.GlobalEventBroadcaster" ) ) );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE(
+ xIfc.is(),
+ "Could not instanciate com.sun.star.frame.GlobalEventBroadcaster" );
+
+ if ( xIfc.is() )
+ {
+ uno::Reference< document::XEventBroadcaster > xBC(
+ xIfc, uno::UNO_QUERY );
+
+ OSL_ENSURE(
+ xBC.is(),
+ "com.sun.star.frame.GlobalEventBroadcaster does not implement "
+ "interface com.sun.star.document.XEventBroadcaster!" );
+
+ return xBC;
+ }
+ else
+ return uno::Reference< document::XEventBroadcaster >();
+}
+
+//=========================================================================
+void OfficeDocumentsManager::buildDocumentsList()
+{
+ OSL_ENSURE( m_xDocEvtNotifier.is(),
+ "OfficeDocumentsManager::buildDocumentsList - "
+ "No document event notifier!" );
+
+ uno::Reference< container::XEnumerationAccess > xEnumAccess(
+ m_xDocEvtNotifier, uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XEnumeration > xEnum
+ = xEnumAccess->createEnumeration();
+
+ osl::MutexGuard aGuard( m_aMtx );
+
+ while ( xEnum->hasMoreElements() )
+ {
+ uno::Any aValue = xEnum->nextElement();
+ // container::NoSuchElementException
+ // lang::WrappedTargetException
+
+ try
+ {
+ uno::Reference< frame::XModel > xModel;
+ aValue >>= xModel;
+
+ if ( xModel.is() )
+ {
+ if ( isOfficeDocument( xModel ) )
+ {
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ if ( (*it).second.xModel == xModel )
+ {
+ // already known.
+ break;
+ }
+ ++it;
+ }
+
+ if ( it == m_aDocs.end() )
+ {
+ // new document
+ rtl::OUString aDocId = getDocumentId( xModel );
+ rtl::OUString aTitle = DocumentInfo::getDocumentTitle( xModel );
+
+ uno::Reference< document::XStorageBasedDocument >
+ xDoc( xModel, uno::UNO_QUERY );
+ OSL_ENSURE( xDoc.is(),
+ "Got no document::XStorageBasedDocument!" );
+
+ uno::Reference< embed::XStorage > xStorage
+ = xDoc->getDocumentStorage();
+ OSL_ENSURE( xDoc.is(), "Got no document storage!" );
+
+ m_aDocs[ aDocId ]
+ = StorageInfo( aTitle, xStorage, xModel );
+ }
+ }
+ }
+ }
+ catch ( lang::DisposedException const & )
+ {
+ // Note: Due to race conditions the XEnumeration can
+ // contains docs that already have been closed
+ }
+ }
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+OfficeDocumentsManager::queryStorage( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return uno::Reference< embed::XStorage >();
+
+ return (*it).second.xStorage;
+}
+
+//=========================================================================
+rtl::OUString OfficeDocumentsManager::queryDocumentId(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ return getDocumentId( xModel );
+}
+
+//=========================================================================
+uno::Reference< frame::XModel >
+OfficeDocumentsManager::queryDocumentModel( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return uno::Reference< frame::XModel >();
+
+ return (*it).second.xModel;
+}
+
+//=========================================================================
+uno::Sequence< rtl::OUString > OfficeDocumentsManager::queryDocuments()
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ uno::Sequence< rtl::OUString > aRet( m_aDocs.size() );
+ sal_Int32 nPos = 0;
+
+ DocumentList::const_iterator it = m_aDocs.begin();
+ while ( it != m_aDocs.end() )
+ {
+ aRet[ nPos ] = (*it).first;
+ ++it;
+ ++nPos;
+ }
+ return aRet;
+}
+
+//=========================================================================
+rtl::OUString
+OfficeDocumentsManager::queryStorageTitle( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( m_aMtx );
+
+ DocumentList::const_iterator it = m_aDocs.find( rDocId );
+ if ( it == m_aDocs.end() )
+ return rtl::OUString();
+
+ return (*it).second.aTitle;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isDocumentPreview(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ ::comphelper::NamedValueCollection aArgs(
+ xModel->getArgs() );
+ sal_Bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False );
+ return bIsPreview;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isHelpDocument(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ ::rtl::OUString sURL( xModel->getURL() );
+ if ( sURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.help://" ) ) )
+ return true;
+
+ return false;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !xModel.is() )
+ return false;
+
+ uno::Reference< frame::XController > xController
+ = xModel->getCurrentController();
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XFrame > xFrame
+ = xController->getFrame();
+ if ( xFrame.is() )
+ {
+ // don't use XFrame::isTop here. This nowadays excludes
+ // "sub documents" such as forms embedded in database documents
+ uno::Reference< awt::XTopWindow > xFrameContainer(
+ xFrame->getContainerWindow(), uno::UNO_QUERY );
+ if ( !xFrameContainer.is() )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isBasicIDE(
+ const uno::Reference< frame::XModel > & xModel )
+{
+ if ( !m_xModuleMgr.is() )
+ {
+ osl::MutexGuard aGuard( m_aMtx );
+ if ( !m_xModuleMgr.is() )
+ {
+ try
+ {
+ m_xModuleMgr
+ = uno::Reference<
+ frame::XModuleManager >(
+ m_xSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.ModuleManager" ) ) ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ OSL_ENSURE( m_xModuleMgr .is(),
+ "Could not instanciate ModuleManager service!" );
+ }
+ }
+
+ if ( m_xModuleMgr.is() )
+ {
+ rtl::OUString aModule;
+ try
+ {
+ aModule = m_xModuleMgr->identify( xModel );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( frame::UnknownModuleException const & )
+ {
+ OSL_ENSURE( false, "Caught UnknownModuleException!" );
+ }
+
+ if ( aModule.getLength() > 0 )
+ {
+ // Filter unwanted items, that are no real documents.
+ if ( aModule.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.script.BasicIDE" ) ) )
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//=========================================================================
+bool OfficeDocumentsManager::isOfficeDocument(
+ const uno::Reference< uno::XInterface > & xDoc )
+{
+ uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+ uno::Reference< document::XStorageBasedDocument >
+ xStorageBasedDoc( xModel, uno::UNO_QUERY );
+ if ( !xStorageBasedDoc.is() )
+ return false;
+
+ if ( !isWithoutOrInTopLevelFrame( xModel ) )
+ return false;
+
+ if ( isDocumentPreview( xModel ) )
+ return false;
+
+ if ( isHelpDocument( xModel ) )
+ return false;
+
+ if ( isBasicIDE( xModel ) )
+ return false;
+
+ return true;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_docmgr.hxx b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
new file mode 100644
index 000000000000..8f8b2fc117f0
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_docmgr.hxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DOCMGR_HXX
+#define INCLUDED_TDOC_DOCMGR_HXX
+
+#include <map>
+
+#include "osl/mutex.hxx"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "com/sun/star/document/XEventBroadcaster.hpp"
+#include "com/sun/star/document/XEventListener.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/frame/XModuleManager.hpp"
+
+namespace tdoc_ucp {
+
+ class OfficeDocumentsEventListener
+ {
+ public:
+ virtual void notifyDocumentOpened( const rtl::OUString & rDocId ) = 0;
+ virtual void notifyDocumentClosed( const rtl::OUString & rDocId ) = 0;
+ };
+
+ //=======================================================================
+
+ struct StorageInfo
+ {
+ rtl::OUString aTitle;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > xStorage;
+ com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > xModel;
+
+ StorageInfo() {}; // needed for STL map only.
+
+ StorageInfo(
+ const rtl::OUString & rTitle,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & rxStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & rxModel )
+ : aTitle( rTitle ), xStorage( rxStorage ), xModel( rxModel ) {}
+ };
+
+ //=======================================================================
+
+ struct ltref
+ {
+ bool operator()(
+ const rtl::OUString & r1, const rtl::OUString & r2 ) const
+ {
+ return r1 < r2;
+ }
+ };
+
+ typedef std::map< rtl::OUString, StorageInfo, ltref > DocumentList;
+
+ //=======================================================================
+
+ class OfficeDocumentsManager :
+ public cppu::WeakImplHelper1< com::sun::star::document::XEventListener >
+ {
+ public:
+ OfficeDocumentsManager(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ OfficeDocumentsEventListener * pDocEventListener );
+ virtual ~OfficeDocumentsManager();
+
+ void destroy();
+
+ // document::XEventListener
+ virtual void SAL_CALL notifyEvent(
+ const com::sun::star::document::EventObject & Event )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // lang::XEventListener (base of document::XEventListener)
+ virtual void SAL_CALL disposing(
+ const com::sun::star::lang::EventObject & Source )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // Non-interface
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const rtl::OUString & rDocId );
+
+ rtl::OUString
+ queryDocumentId(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XModel >
+ queryDocumentModel( const rtl::OUString & rDocId );
+
+ com::sun::star::uno::Sequence< rtl::OUString >
+ queryDocuments();
+
+ rtl::OUString
+ queryStorageTitle( const rtl::OUString & rDocId );
+
+ private:
+ static com::sun::star::uno::Reference<
+ com::sun::star::document::XEventBroadcaster >
+ createDocumentEventNotifier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ void buildDocumentsList();
+ bool
+ isOfficeDocument(
+ const com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > & xDoc );
+
+ bool
+ isDocumentPreview(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isWithoutOrInTopLevelFrame(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isBasicIDE(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ bool
+ isHelpDocument(
+ const com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel > & xModel );
+
+ osl::Mutex m_aMtx;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::document::XEventBroadcaster > m_xDocEvtNotifier;
+ com::sun::star::uno::Reference<
+ com::sun::star::frame::XModuleManager > m_xModuleMgr;
+ DocumentList m_aDocs;
+ OfficeDocumentsEventListener * m_pDocEventListener;
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DOCMGR_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx
new file mode 100644
index 000000000000..72c5f700aa2c
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "cppuhelper/factory.hxx"
+
+#include "tdoc_documentcontentfactory.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DocumentContentFactory Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DocumentContentFactory::DocumentContentFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
+: m_xSMgr( xSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+DocumentContentFactory::~DocumentContentFactory()
+{
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+// virtual
+::rtl::OUString SAL_CALL DocumentContentFactory::getImplementationName()
+ throw ( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL
+DocumentContentFactory::supportsService( const ::rtl::OUString& ServiceName )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames();
+ const rtl::OUString * pArray = aSNL.getConstArray();
+ for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ {
+ if ( pArray[ i ] == ServiceName )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ::rtl::OUString > SAL_CALL
+DocumentContentFactory::getSupportedServiceNames()
+ throw ( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+//=========================================================================
+// static
+rtl::OUString DocumentContentFactory::getImplementationName_Static()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.TransientDocumentsDocumentContentFactory" ) );
+}
+
+//=========================================================================
+// static
+uno::Sequence< rtl::OUString >
+DocumentContentFactory::getSupportedServiceNames_Static()
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[ 0 ]
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.frame.TransientDocumentsDocumentContentFactory" ) );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XTransientDocumentsDocumentContentFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+DocumentContentFactory::createDocumentContent(
+ const uno::Reference< frame::XModel >& Model )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ uno::Reference< frame::XTransientDocumentsDocumentContentFactory > xDocFac;
+ try
+ {
+ xDocFac
+ = uno::Reference< frame::XTransientDocumentsDocumentContentFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb.TransientDocumentsContentProvider" ) )
+ ),
+ uno::UNO_QUERY );
+ }
+ catch ( uno::Exception const & )
+ {
+ // handled below.
+ }
+
+ if ( xDocFac.is() )
+ return xDocFac->createDocumentContent( Model );
+
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unable to obtain document content factory!" ) ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+static uno::Reference< uno::XInterface > SAL_CALL
+DocumentContentFactory_CreateInstance(
+ const uno::Reference< lang::XMultiServiceFactory> & rSMgr )
+ throw( uno::Exception )
+{
+ lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >(
+ new DocumentContentFactory( rSMgr ) );
+ return uno::Reference< uno::XInterface >::query( pX );
+}
+
+//=========================================================================
+// static
+uno::Reference< lang::XSingleServiceFactory >
+DocumentContentFactory::createServiceFactory(
+ const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr )
+{
+ return uno::Reference< lang::XSingleServiceFactory >(
+ cppu::createOneInstanceFactory(
+ rxServiceMgr,
+ DocumentContentFactory::getImplementationName_Static(),
+ DocumentContentFactory_CreateInstance,
+ DocumentContentFactory::getSupportedServiceNames_Static() ) );
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx
new file mode 100644
index 000000000000..7a2d919e5708
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_documentcontentfactory.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX
+#define INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX
+
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp"
+
+#include "cppuhelper/implbase2.hxx"
+
+namespace tdoc_ucp {
+
+class DocumentContentFactory :
+ public cppu::WeakImplHelper2<
+ com::sun::star::frame::XTransientDocumentsDocumentContentFactory,
+ com::sun::star::lang::XServiceInfo >
+{
+public:
+ DocumentContentFactory( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~DocumentContentFactory();
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTransientDocumentsDocumentContentFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createDocumentContent( const ::com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel >& Model )
+ throw ( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+
+ // Non-UNO interfaces
+ static rtl::OUString
+ getImplementationName_Static();
+ static com::sun::star::uno::Sequence< rtl::OUString >
+ getSupportedServiceNames_Static();
+
+ static com::sun::star::uno::Reference<
+ com::sun::star::lang::XSingleServiceFactory >
+ createServiceFactory( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & rxServiceMgr );
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_DOCUMENTCONTENTFACTORY_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx b/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx
new file mode 100644
index 000000000000..c7ce1b893372
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_passwordrequest.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "osl/mutex.hxx"
+
+#include "com/sun/star/lang/XTypeProvider.hpp"
+#include "com/sun/star/task/DocumentPasswordRequest.hpp"
+
+#include "cppuhelper/typeprovider.hxx"
+#include "ucbhelper/interactionrequest.hxx"
+
+#include "tdoc_passwordrequest.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+namespace tdoc_ucp
+{
+ class InteractionSupplyPassword :
+ public ucbhelper::InteractionContinuation,
+ public lang::XTypeProvider,
+ public task::XInteractionPassword
+ {
+ public:
+ InteractionSupplyPassword( ucbhelper::InteractionRequest * pRequest )
+ : InteractionContinuation( pRequest ) {}
+
+ // XInterface
+ virtual uno::Any SAL_CALL queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL acquire()
+ throw ();
+ virtual void SAL_CALL release()
+ throw ();
+
+ // XTypeProvider
+ virtual uno::Sequence< uno::Type > SAL_CALL getTypes()
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
+ throw ( uno::RuntimeException );
+
+ // XInteractionContinuation
+ virtual void SAL_CALL select()
+ throw ( uno::RuntimeException );
+
+ // XInteractionPassword
+ virtual void SAL_CALL setPassword( const rtl::OUString & aPasswd )
+ throw ( uno::RuntimeException );
+ virtual rtl::OUString SAL_CALL getPassword()
+ throw ( uno::RuntimeException );
+
+ private:
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aPassword;
+ };
+} // namespace tdoc_ucp
+
+//=========================================================================
+//=========================================================================
+//
+// InteractionSupplyPassword Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL InteractionSupplyPassword::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL InteractionSupplyPassword::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL
+InteractionSupplyPassword::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = cppu::queryInterface( rType,
+ static_cast< lang::XTypeProvider * >( this ),
+ static_cast< task::XInteractionContinuation * >( this ),
+ static_cast< task::XInteractionPassword * >( this ) );
+
+ return aRet.hasValue()
+ ? aRet : InteractionContinuation::queryInterface( rType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL
+InteractionSupplyPassword::getImplementationId()
+ throw( uno::RuntimeException )
+{
+ static cppu::OImplementationId * pId = 0;
+ if ( !pId )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pId )
+ {
+ static cppu::OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return (*pId).getImplementationId();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL InteractionSupplyPassword::getTypes()
+ throw( uno::RuntimeException )
+{
+ static cppu::OTypeCollection * pCollection = 0;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection collection(
+ getCppuType( static_cast<
+ uno::Reference< lang::XTypeProvider > * >( 0 ) ),
+ getCppuType( static_cast<
+ uno::Reference< task::XInteractionPassword > * >( 0 ) ) );
+ pCollection = &collection;
+ }
+ }
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XInteractionContinuation methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL InteractionSupplyPassword::select()
+ throw( uno::RuntimeException )
+{
+ recordSelection();
+}
+
+//=========================================================================
+//
+// XInteractionPassword methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+InteractionSupplyPassword::setPassword( const ::rtl::OUString& aPasswd )
+ throw ( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ m_aPassword = aPasswd;
+}
+
+// virtual
+rtl::OUString SAL_CALL InteractionSupplyPassword::getPassword()
+ throw ( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ return m_aPassword;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// DocumentPasswordRequest Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DocumentPasswordRequest::DocumentPasswordRequest(
+ task::PasswordRequestMode eMode,
+ const rtl::OUString & rDocumentName )
+{
+ // Fill request...
+ task::DocumentPasswordRequest aRequest;
+// aRequest.Message = // OUString
+// aRequest.Context = // XInterface
+ aRequest.Classification = task::InteractionClassification_ERROR;
+ aRequest.Mode = eMode;
+ aRequest.Name = rDocumentName;
+
+ setRequest( uno::makeAny( aRequest ) );
+
+ // Fill continuations...
+ uno::Sequence<
+ uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
+ aContinuations[ 0 ] = new ucbhelper::InteractionAbort( this );
+ aContinuations[ 1 ] = new ucbhelper::InteractionRetry( this );
+ aContinuations[ 2 ] = new InteractionSupplyPassword( this );
+
+ setContinuations( aContinuations );
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx b/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx
new file mode 100644
index 000000000000..bc170bece65b
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_passwordrequest.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_PASSWORDREQUEST_HXX
+#define INCLUDED_TDOC_PASSWORDREQUEST_HXX
+
+#include "com/sun/star/task/PasswordRequestMode.hpp"
+#include "com/sun/star/task/XInteractionPassword.hpp"
+
+#include "ucbhelper/interactionrequest.hxx"
+
+namespace tdoc_ucp {
+
+ /*
+ @usage:
+
+ uno::Reference< ucb::XCommandEnvironment > Environment = ...;
+
+ if ( Environment.is() )
+ {
+ uno::Reference< task::XInteractionHandler > xIH
+ = Environment->getInteractionHandler();
+ if ( xIH.is() )
+ {
+ rtl::Reference< DocumentPasswordRequest > xRequest
+ = new DocumentPasswordRequest(
+ task::PasswordRequestMode_PASSWORD_ENTER,
+ m_xIdentifier->getContentIdentifier() );
+ xIH->handle( xRequest.get() );
+
+ rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+ = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ // Handler handled the request.
+ uno::Reference< task::XInteractionAbort > xAbort(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xAbort.is() )
+ {
+ // @@@
+ }
+
+ uno::Reference< task::XInteractionRetry > xRetry(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xRetry.is() )
+ {
+ // @@@
+ }
+
+ uno::Reference< task::XInteractionPassword > xPassword(
+ xSelection.get(), uno::UNO_QUERY );
+ if ( xPassword.is() )
+ {
+ rtl::OUString aPassword = xPassword->getPassword();
+
+ // @@@
+ }
+ }
+ }
+ }
+
+ */
+
+ class DocumentPasswordRequest : public ucbhelper::InteractionRequest
+ {
+ public:
+ DocumentPasswordRequest(
+ com::sun::star::task::PasswordRequestMode eMode,
+ const rtl::OUString & rDocumentName );
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_PASSWORDREQUEST_HXX */
+
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.cxx b/ucb/source/ucp/tdoc/tdoc_provider.cxx
new file mode 100644
index 000000000000..7ffedfcf1932
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_provider.cxx
@@ -0,0 +1,629 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/embed/XStorage.hpp"
+
+#include "ucbhelper/contentidentifier.hxx"
+
+#include "tdoc_provider.hxx"
+#include "tdoc_content.hxx"
+#include "tdoc_uri.hxx"
+#include "tdoc_docmgr.hxx"
+#include "tdoc_storage.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ContentProvider::ContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
+: ::ucbhelper::ContentProviderImplHelper( xSMgr ),
+ m_xDocsMgr( new OfficeDocumentsManager( xSMgr, this ) ),
+ m_xStgElemFac( new StorageElementFactory( xSMgr, m_xDocsMgr ) )
+{
+}
+
+//=========================================================================
+// virtual
+ContentProvider::~ContentProvider()
+{
+ if ( m_xDocsMgr.is() )
+ m_xDocsMgr->destroy();
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ frame::XTransientDocumentsDocumentContentFactory );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( ContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ frame::XTransientDocumentsDocumentContentFactory );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1(
+ ContentProvider,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.TransientDocumentsContentProvider" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ TDOC_CONTENT_PROVIDER_SERVICE_NAME ) ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+ContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ Uri aUri( Identifier->getContentIdentifier() );
+ if ( !aUri.isValid() )
+ throw ucb::IllegalIdentifierException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid URL!" ) ),
+ Identifier );
+
+ // Normalize URI.
+ uno::Reference< ucb::XContentIdentifier > xCanonicId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xCanonicId ).get();
+
+ if ( !xContent.is() )
+ {
+ // Create a new content.
+ xContent = Content::create( m_xSMgr, this, xCanonicId );
+ registerNewContent( xContent );
+ }
+
+ return xContent;
+}
+
+//=========================================================================
+//
+// XTransientDocumentsDocumentContentFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+ContentProvider::createDocumentContent(
+ const uno::Reference< frame::XModel >& Model )
+ throw ( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ // model -> id -> content identifier -> queryContent
+ if ( m_xDocsMgr.is() )
+ {
+ rtl::OUString aDocId = m_xDocsMgr->queryDocumentId( Model );
+ if ( aDocId.getLength() > 0 )
+ {
+ rtl::OUStringBuffer aBuffer;
+ aBuffer.appendAscii( TDOC_URL_SCHEME ":/" );
+ aBuffer.append( aDocId );
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier(
+ m_xSMgr, aBuffer.makeStringAndClear() );
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // Check, if a content with given id already exists...
+ uno::Reference< ucb::XContent > xContent
+ = queryExistingContent( xId ).get();
+
+ if ( !xContent.is() )
+ {
+ // Create a new content.
+ xContent = Content::create( m_xSMgr, this, xId );
+ }
+
+ if ( xContent.is() )
+ return xContent;
+
+ // no content.
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Illegal Content Identifier!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unable to obtain document id from model!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+ }
+ else
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No Document Manager!" ) ),
+ static_cast< cppu::OWeakObject * >( this ),
+ 1 );
+ }
+}
+
+//=========================================================================
+//
+// interface OfficeDocumentsEventListener
+//
+//=========================================================================
+
+// virtual
+void ContentProvider::notifyDocumentClosed( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( getContentListMutex() );
+
+ ::ucbhelper::ContentRefList aAllContents;
+ queryExistingContents( aAllContents );
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ // Notify all content objects related to the closed doc.
+
+ bool bFoundDocumentContent = false;
+ rtl::Reference< Content > xRoot;
+
+ while ( it != end )
+ {
+ Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
+ OSL_ENSURE( aUri.isValid(),
+ "ContentProvider::notifyDocumentClosed - Invalid URI!" );
+
+ if ( !bFoundDocumentContent )
+ {
+ if ( aUri.isRoot() )
+ {
+ xRoot = static_cast< Content * >( (*it).get() );
+ }
+ else if ( aUri.isDocument() )
+ {
+ if ( aUri.getDocumentId() == rDocId )
+ {
+ bFoundDocumentContent = true;
+
+ // document content will notify removal of child itself;
+ // no need for the root to propagate this.
+ xRoot.clear();
+ }
+ }
+ }
+
+ if ( aUri.getDocumentId() == rDocId )
+ {
+ // Inform content.
+ rtl::Reference< Content > xContent
+ = static_cast< Content * >( (*it).get() );
+
+ xContent->notifyDocumentClosed();
+ }
+
+ ++it;
+ }
+
+ if ( xRoot.is() )
+ {
+ // No document content found for rDocId but root content
+ // instanciated. Root content must announce document removal
+ // to content event listeners.
+ xRoot->notifyChildRemoved( rDocId );
+ }
+}
+
+//=========================================================================
+// virtual
+void ContentProvider::notifyDocumentOpened( const rtl::OUString & rDocId )
+{
+ osl::MutexGuard aGuard( getContentListMutex() );
+
+ ::ucbhelper::ContentRefList aAllContents;
+ queryExistingContents( aAllContents );
+
+ ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
+ ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
+
+ // Find root content. If instanciated let it propagate document insertion.
+
+ while ( it != end )
+ {
+ Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
+ OSL_ENSURE( aUri.isValid(),
+ "ContentProvider::notifyDocumentOpened - Invalid URI!" );
+
+ if ( aUri.isRoot() )
+ {
+ rtl::Reference< Content > xRoot
+ = static_cast< Content * >( (*it).get() );
+ xRoot->notifyChildInserted( rDocId );
+
+ // Done.
+ break;
+ }
+
+ ++it;
+ }
+}
+
+//=========================================================================
+//
+// Non-UNO
+//
+//=========================================================================
+
+uno::Reference< embed::XStorage >
+ContentProvider::queryStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode ) const
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createStorage( rUri, eMode );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+ return uno::Reference< embed::XStorage >();
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+ContentProvider::queryStorageClone( const rtl::OUString & rUri ) const
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ Uri aUri( rUri );
+ uno::Reference< embed::XStorage > xParentStorage
+ = m_xStgElemFac->createStorage( aUri.getParentUri(), READ );
+ uno::Reference< embed::XStorage > xStorage
+ = m_xStgElemFac->createTemporaryStorage();
+
+ xParentStorage->copyStorageElementLastCommitTo(
+ aUri.getDecodedName(), xStorage );
+ return xStorage;
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+
+ return uno::Reference< embed::XStorage >();
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream >
+ContentProvider::queryInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createInputStream( rUri, rPassword );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XInputStream >();
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream >
+ContentProvider::queryOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return
+ m_xStgElemFac->createOutputStream( rUri, rPassword, bTruncate );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XOutputStream >();
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+ContentProvider::queryStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( packages::WrongPasswordException )
+{
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ return m_xStgElemFac->createStream( rUri, rPassword, bTruncate );
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance when the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
+ }
+// catch ( packages::WrongPasswordException const & )
+// {
+// // the key provided is wrong; rethrow; to be handled by caller.
+// throw;
+// }
+ }
+ return uno::Reference< io::XStream >();
+}
+
+//=========================================================================
+bool ContentProvider::queryNamesOfChildren(
+ const rtl::OUString & rUri, uno::Sequence< rtl::OUString > & rNames ) const
+{
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ // special handling for root, which has no storage, but children.
+ if ( m_xDocsMgr.is() )
+ {
+ rNames = m_xDocsMgr->queryDocuments();
+ return true;
+ }
+ }
+ else
+ {
+ if ( m_xStgElemFac.is() )
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xStorage
+ = m_xStgElemFac->createStorage( rUri, READ );
+
+ OSL_ENSURE( xStorage.is(), "Got no Storage!" );
+
+ if ( xStorage.is() )
+ {
+ uno::Reference< container::XNameAccess > xNA(
+ xStorage, uno::UNO_QUERY );
+
+ OSL_ENSURE( xNA.is(), "Got no css.container.XNameAccess!" );
+ if ( xNA.is() )
+ {
+ rNames = xNA->getElementNames();
+ return true;
+ }
+ }
+ }
+ catch ( embed::InvalidStorageException const & )
+ {
+ OSL_ENSURE( false, "Caught InvalidStorageException!" );
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ OSL_ENSURE( false, "Caught IllegalArgumentException!" );
+ }
+ catch ( io::IOException const & )
+ {
+ // Okay to happen, for instance if the storage does not exist.
+ //OSL_ENSURE( false, "Caught IOException!" );
+ }
+ catch ( embed::StorageWrappedTargetException const & )
+ {
+ OSL_ENSURE( false,
+ "Caught embed::StorageWrappedTargetException!" );
+ }
+ }
+ }
+ return false;
+}
+
+//=========================================================================
+rtl::OUString
+ContentProvider::queryStorageTitle( const rtl::OUString & rUri ) const
+{
+ rtl::OUString aTitle;
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ // always empty.
+ aTitle = rtl::OUString();
+ }
+ else if ( aUri.isDocument() )
+ {
+ // for documents, title shall not be derived from URL. It shall
+ // be somethimg more 'speaking' than just the document UID.
+ if ( m_xDocsMgr.is() )
+ aTitle = m_xDocsMgr->queryStorageTitle( aUri.getDocumentId() );
+ }
+ else
+ {
+ // derive title from URL
+ aTitle = aUri.getDecodedName();
+ }
+
+ OSL_ENSURE( ( aTitle.getLength() > 0 ) || aUri.isRoot(),
+ "ContentProvider::queryStorageTitle - empty title!" );
+ return aTitle;
+}
+
+//=========================================================================
+uno::Reference< frame::XModel >
+ContentProvider::queryDocumentModel( const rtl::OUString & rUri ) const
+{
+ uno::Reference< frame::XModel > xModel;
+
+ if ( m_xDocsMgr.is() )
+ {
+ Uri aUri( rUri );
+ xModel = m_xDocsMgr->queryDocumentModel( aUri.getDocumentId() );
+ }
+
+ OSL_ENSURE( xModel.is(),
+ "ContentProvider::queryDocumentModel - no model!" );
+ return xModel;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_provider.hxx b/ucb/source/ucp/tdoc/tdoc_provider.hxx
new file mode 100644
index 000000000000..70f61e130980
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_provider.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_PROVIDER_HXX
+#define INCLUDED_TDOC_PROVIDER_HXX
+
+#include "rtl/ref.hxx"
+#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp>
+#include <com/sun/star/packages/WrongPasswordException.hpp>
+#include "ucbhelper/providerhelper.hxx"
+#include "tdoc_uri.hxx" // for TDOC_URL_SCHEME
+#include "tdoc_docmgr.hxx"
+#include "tdoc_storage.hxx" // for StorageAccessMode
+
+namespace com { namespace sun { namespace star { namespace embed {
+ class XStorage;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace frame {
+ class XModel;
+} } } }
+
+namespace tdoc_ucp {
+
+//=========================================================================
+
+#define TDOC_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.TransientDocumentsContentProvider"
+#define TDOC_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 50
+
+#define TDOC_ROOT_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-root"
+#define TDOC_DOCUMENT_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-document"
+#define TDOC_FOLDER_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-folder"
+#define TDOC_STREAM_CONTENT_TYPE \
+ "application/" TDOC_URL_SCHEME "-stream"
+
+//=========================================================================
+
+class StorageElementFactory;
+
+class ContentProvider :
+ public ::ucbhelper::ContentProviderImplHelper,
+ public com::sun::star::frame::XTransientDocumentsDocumentContentFactory,
+ public OfficeDocumentsEventListener
+{
+public:
+ ContentProvider( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~ContentProvider();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XContentProvider
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ throw( com::sun::star::ucb::IllegalIdentifierException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTransientDocumentsDocumentContentFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContent > SAL_CALL
+ createDocumentContent( const ::com::sun::star::uno::Reference<
+ com::sun::star::frame::XModel >& Model )
+ throw ( com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::uno::RuntimeException );
+
+ // Non-UNO interfaces
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const rtl::OUString & rUri, StorageAccessMode eMode ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorageClone( const rtl::OUString & rUri ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ queryInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >
+ queryOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ queryStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate ) const
+ throw ( com::sun::star::packages::WrongPasswordException );
+
+ bool queryNamesOfChildren(
+ const rtl::OUString & rUri,
+ com::sun::star::uno::Sequence< rtl::OUString > & rNames ) const;
+
+ // storage properties
+ rtl::OUString queryStorageTitle( const rtl::OUString & rUri ) const;
+
+ com::sun::star::uno::Reference< com::sun::star::frame::XModel >
+ queryDocumentModel( const rtl::OUString & rUri ) const;
+
+ // interface OfficeDocumentsEventListener
+ virtual void notifyDocumentOpened( const rtl::OUString & rDocId );
+ virtual void notifyDocumentClosed( const rtl::OUString & rDocId );
+
+private:
+ rtl::Reference< OfficeDocumentsManager > m_xDocsMgr;
+ rtl::Reference< StorageElementFactory > m_xStgElemFac;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_PROVIDER_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_resultset.cxx b/ucb/source/ucp/tdoc/tdoc_resultset.cxx
new file mode 100644
index 000000000000..d8212fa028bb
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_resultset.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - This implementation is not a dynamic result set!!! It only implements
+ the necessary interfaces, but never recognizes/notifies changes!!!
+
+ *************************************************************************/
+
+#include "ucbhelper/resultset.hxx"
+
+#include "tdoc_datasupplier.hxx"
+#include "tdoc_resultset.hxx"
+#include "tdoc_content.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const ucb::OpenCommandArgument2& rCommand )
+: ResultSetImplHelper( rxSMgr, rCommand ),
+ m_xContent( rxContent )
+{
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+void DynamicResultSet::initStatic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new ResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new ResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_resultset.hxx b/ucb/source/ucp/tdoc/tdoc_resultset.hxx
new file mode 100644
index 000000000000..a3e420894ade
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_resultset.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_RESULTSET_HXX
+#define INCLUDED_TDOC_RESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+
+namespace tdoc_ucp {
+
+class Content;
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< Content > m_xContent;
+
+private:
+ virtual void initStatic();
+ virtual void initDynamic();
+
+public:
+ DynamicResultSet(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< Content >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand );
+};
+
+}
+
+#endif /* !INCLUDED_TDOC_RESULTSET_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_services.cxx b/ucb/source/ucp/tdoc/tdoc_services.cxx
new file mode 100644
index 000000000000..6f9641d5159b
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_services.cxx
@@ -0,0 +1,151 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+
+#include "tdoc_provider.hxx"
+#include "tdoc_documentcontentfactory.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+static sal_Bool writeInfo( void * pRegistryKey,
+ const rtl::OUString & rImplementationName,
+ uno::Sequence< rtl::OUString > const & rServiceNames )
+{
+ rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) );
+ aKeyName += rImplementationName;
+ aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" );
+
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< registry::XRegistryKey * >(
+ pRegistryKey )->createKey( aKeyName );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ }
+
+ if ( !xKey.is() )
+ return sal_False;
+
+ sal_Bool bSuccess = sal_True;
+
+ for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n )
+ {
+ try
+ {
+ xKey->createKey( rServiceNames[ n ] );
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ bSuccess = sal_False;
+ break;
+ }
+ }
+ return bSuccess;
+}
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" sal_Bool SAL_CALL component_writeInfo(
+ void * /*pServiceManager*/, void * pRegistryKey )
+{
+ return pRegistryKey &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ ContentProvider::getImplementationName_Static(),
+ ContentProvider::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Document Content Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ DocumentContentFactory::getImplementationName_Static(),
+ DocumentContentFactory::getSupportedServiceNames_Static() );
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xSMgr(
+ reinterpret_cast< lang::XMultiServiceFactory * >(
+ pServiceManager ) );
+ uno::Reference< lang::XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( ContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = ContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Transient Documents Document Content Factory.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( DocumentContentFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = DocumentContentFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.cxx b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
new file mode 100644
index 000000000000..0bd25f94d096
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.cxx
@@ -0,0 +1,1108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - remove root storage access workaround
+
+ *************************************************************************/
+
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/reflection/XProxyFactory.hpp"
+
+#include "tdoc_uri.hxx"
+
+#include "tdoc_stgelems.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// ParentStorageHolder Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+ParentStorageHolder::ParentStorageHolder(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri )
+: m_xParentStorage( xParentStorage ),
+ m_bParentIsRootStorage( false )
+{
+ Uri aUri( rUri );
+ if ( aUri.isDocument() )
+ m_bParentIsRootStorage = true;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Storage Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+Storage::Storage( const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< StorageElementFactory > & xFactory,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< embed::XStorage > & xStorageToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xFactory( xFactory ),
+ m_xWrappedStorage( xStorageToWrap ),
+ m_xWrappedTransObj( xStorageToWrap, uno::UNO_QUERY ), // optional interface
+ m_xWrappedComponent( xStorageToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStorageToWrap, uno::UNO_QUERY ),
+ m_bIsDocumentStorage( Uri( rUri ).isDocument() )
+{
+ OSL_ENSURE( m_xWrappedStorage.is(),
+ "Storage::Storage: No storage to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "Storage::Storage: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "Storage::Storage: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStorage );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "Storage::Storage: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "Storage::Storage: Wrapped storage cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+Storage::~Storage()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+
+ // Never dispose a document storage. Not owner!
+ if ( !isDocumentStorage() )
+ {
+ if ( m_xWrappedComponent.is() )
+ {
+ // "Auto-dispose"...
+ try
+ {
+ m_xWrappedComponent->dispose();
+ }
+ catch ( lang::DisposedException const & )
+ {
+ // might happen.
+ }
+ catch ( ... )
+ {
+ OSL_ENSURE( false, "Storage::~Storage - Caught exception!" );
+ }
+ }
+ }
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Storage::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ // First, try to use interfaces implemented by myself and base class(es)
+ uno::Any aRet = StorageUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ // Try to use requested interface from aggregated storage
+ return m_xAggProxy->queryAggregation( aType );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::acquire()
+ throw ()
+{
+ osl_incrementInterlockedCount( &m_refCount );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::release()
+ throw ()
+{
+ if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
+ {
+ m_xFactory->releaseElement( this );
+ delete this;
+ }
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Storage::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL Storage::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// lang::XComponent (base of embed::XStorage)
+//
+//=========================================================================
+// virtual
+void SAL_CALL Storage::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedStorage->dispose();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedStorage->addEventListener( xListener );
+}
+//=========================================================================
+// virtual
+void SAL_CALL Storage::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw (uno::RuntimeException)
+{
+ m_xWrappedStorage->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// container::XElementAccess (base of container::XNameAccess)
+//
+//=========================================================================
+
+// virtual
+uno::Type SAL_CALL Storage::getElementType()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->getElementType();
+}
+
+//=========================================================================
+// virtual
+::sal_Bool SAL_CALL Storage::hasElements()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->hasElements();
+}
+
+//=========================================================================
+//
+// container::XNameAccess (base of embed::XStorage)
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Storage::getByName( const ::rtl::OUString& aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->getByName( aName );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ::rtl::OUString > SAL_CALL Storage::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->getElementNames();
+}
+
+//=========================================================================
+// virtual
+::sal_Bool SAL_CALL Storage::hasByName( const ::rtl::OUString& aName )
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedStorage->hasByName( aName );
+}
+
+//=========================================================================
+//
+// embed::XStorage
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Storage::copyToStorage(
+ const uno::Reference< embed::XStorage >& xDest )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->copyToStorage( xDest );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::openStreamElement(
+ const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openStreamElement( aStreamName, nOpenMode );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::openEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode,
+ const ::rtl::OUString& aPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openEncryptedStreamElement(
+ aStreamName, nOpenMode, aPassword );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< embed::XStorage > SAL_CALL Storage::openStorageElement(
+ const ::rtl::OUString& aStorName, sal_Int32 nOpenMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->openStorageElement( aStorName, nOpenMode );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::cloneStreamElement(
+ const ::rtl::OUString& aStreamName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->cloneStreamElement( aStreamName );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XStream > SAL_CALL Storage::cloneEncryptedStreamElement(
+ const ::rtl::OUString& aStreamName,
+ const ::rtl::OUString& aPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ packages::NoEncryptionException,
+ packages::WrongPasswordException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->cloneEncryptedStreamElement( aStreamName,
+ aPassword );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyLastCommitTo(
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ m_xWrappedStorage->copyLastCommitTo( xTargetStorage );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyStorageElementLastCommitTo(
+ const ::rtl::OUString& aStorName,
+ const uno::Reference< embed::XStorage >& xTargetStorage )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException)
+{
+ m_xWrappedStorage->copyStorageElementLastCommitTo( aStorName, xTargetStorage );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL Storage::isStreamElement(
+ const ::rtl::OUString& aElementName )
+ throw ( container::NoSuchElementException,
+ lang::IllegalArgumentException,
+ embed::InvalidStorageException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->isStreamElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL Storage::isStorageElement(
+ const ::rtl::OUString& aElementName )
+ throw ( container::NoSuchElementException,
+ lang::IllegalArgumentException,
+ embed::InvalidStorageException,
+ uno::RuntimeException )
+{
+ return m_xWrappedStorage->isStorageElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::removeElement( const ::rtl::OUString& aElementName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->removeElement( aElementName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::renameElement( const ::rtl::OUString& aEleName,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->renameElement( aEleName, aNewName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::copyElementTo(
+ const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->copyElementTo( aElementName, xDest, aNewName );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::moveElementTo(
+ const ::rtl::OUString& aElementName,
+ const uno::Reference< embed::XStorage >& xDest,
+ const ::rtl::OUString& rNewName )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ container::ElementExistException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ m_xWrappedStorage->moveElementTo( aElementName, xDest, rNewName );
+}
+
+//=========================================================================
+//
+// embed::XTransactedObject
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Storage::commit()
+ throw ( io::IOException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ // Never commit a root storage (-> has no parent)!
+ // Would lead in writing the whole document to disk.
+
+ uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
+ if ( xParentStorage.is() )
+ {
+ OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
+
+ if ( m_xWrappedTransObj.is() )
+ {
+ m_xWrappedTransObj->commit();
+
+ if ( !isParentARootStorage() )
+ {
+ uno::Reference< embed::XTransactedObject > xParentTA(
+ xParentStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ xParentTA->commit();
+ }
+ }
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Storage::revert()
+ throw ( io::IOException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xParentStorage = getParentStorage();
+ if ( xParentStorage.is() )
+ {
+ OSL_ENSURE( m_xWrappedTransObj.is(), "No XTransactedObject interface!" );
+
+ if ( m_xWrappedTransObj.is() )
+ {
+ m_xWrappedTransObj->revert();
+
+ if ( !isParentARootStorage() )
+ {
+ uno::Reference< embed::XTransactedObject > xParentTA(
+ xParentStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ xParentTA->revert();
+ }
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// OutputStream Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+OutputStream::OutputStream(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< io::XOutputStream > & xStreamToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xWrappedStream( xStreamToWrap ),
+ m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
+{
+ OSL_ENSURE( m_xWrappedStream.is(),
+ "OutputStream::OutputStream: No stream to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "OutputStream::OutputStream: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "OutputStream::OutputStream: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+OutputStream::~OutputStream()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL OutputStream::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = OutputStreamUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ if ( m_xAggProxy.is() )
+ return m_xAggProxy->queryAggregation( aType );
+ else
+ return uno::Any();
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL OutputStream::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL OutputStream::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// io::XOutputStream
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+OutputStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->writeBytes( aData );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::flush()
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->flush();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::closeOutput( )
+ throw ( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedStream->closeOutput();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+//
+// lang::XComponent
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+OutputStream::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->dispose();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+OutputStream::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->removeEventListener( aListener );
+}
+
+//=========================================================================
+//=========================================================================
+//
+// Stream Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+Stream::Stream(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const uno::Reference< io::XStream > & xStreamToWrap )
+: ParentStorageHolder( xParentStorage, Uri( rUri ).getParentUri() ),
+ m_xWrappedStream( xStreamToWrap ),
+ m_xWrappedOutputStream( xStreamToWrap->getOutputStream() ), // might be empty
+ m_xWrappedTruncate( m_xWrappedOutputStream, uno::UNO_QUERY ), // might be empty
+ m_xWrappedInputStream( xStreamToWrap->getInputStream(), uno::UNO_QUERY ),
+ m_xWrappedComponent( xStreamToWrap, uno::UNO_QUERY ),
+ m_xWrappedTypeProv( xStreamToWrap, uno::UNO_QUERY )
+{
+ OSL_ENSURE( m_xWrappedStream.is(),
+ "OutputStream::OutputStream: No stream to wrap!" );
+
+ OSL_ENSURE( m_xWrappedComponent.is(),
+ "OutputStream::OutputStream: No component to wrap!" );
+
+ OSL_ENSURE( m_xWrappedTypeProv.is(),
+ "OutputStream::OutputStream: No Type Provider!" );
+
+ // Use proxy factory service to create aggregatable proxy.
+ try
+ {
+ uno::Reference< reflection::XProxyFactory > xProxyFac(
+ xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.reflection.ProxyFactory" ) ) ),
+ uno::UNO_QUERY );
+ if ( xProxyFac.is() )
+ {
+ m_xAggProxy = xProxyFac->createProxy( m_xWrappedStream );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false, "OutputStream::OutputStream: Caught exception!" );
+ }
+
+ OSL_ENSURE( m_xAggProxy.is(),
+ "OutputStream::OutputStream: Wrapped stream cannot be aggregated!" );
+
+ if ( m_xAggProxy.is() )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ // Solaris compiler problem:
+ // Extra block to enforce destruction of temporary object created
+ // in next statement _before_ osl_decrementInterlockedCount is
+ // called. Otherwise 'this' will destroy itself even before ctor
+ // is completed (See impl. of XInterface::release())!
+
+ m_xAggProxy->setDelegator(
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+}
+
+//=========================================================================
+// virtual
+Stream::~Stream()
+{
+ if ( m_xAggProxy.is() )
+ m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
+}
+
+//=========================================================================
+//
+// uno::XInterface
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL Stream::queryInterface( const uno::Type& aType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = StreamUNOBase::queryInterface( aType );
+
+ if ( aRet.hasValue() )
+ return aRet;
+
+ if ( m_xAggProxy.is() )
+ return m_xAggProxy->queryAggregation( aType );
+ else
+ return uno::Any();
+}
+
+//=========================================================================
+//
+// lang::XTypeProvider
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< uno::Type > SAL_CALL Stream::getTypes()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getTypes();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< sal_Int8 > SAL_CALL Stream::getImplementationId()
+ throw ( uno::RuntimeException )
+{
+ return m_xWrappedTypeProv->getImplementationId();
+}
+
+//=========================================================================
+//
+// io::XStream.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< io::XInputStream > SAL_CALL Stream::getInputStream()
+ throw( uno::RuntimeException )
+{
+ return uno::Reference< io::XInputStream >( this );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< io::XOutputStream > SAL_CALL Stream::getOutputStream()
+ throw( uno::RuntimeException )
+{
+ return uno::Reference< io::XOutputStream >( this );
+}
+
+//=========================================================================
+//
+// io::XOutputStream.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->writeBytes( aData );
+ commitChanges();
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::flush()
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->flush();
+ commitChanges();
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::closeOutput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedOutputStream.is() )
+ {
+ m_xWrappedOutputStream->closeOutput();
+ commitChanges();
+ }
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+//
+// io::XTruncate.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::truncate()
+ throw( io::IOException,
+ uno::RuntimeException )
+{
+ if ( m_xWrappedTruncate.is() )
+ {
+ m_xWrappedTruncate->truncate();
+ commitChanges();
+ }
+}
+
+//=========================================================================
+//
+// io::XInputStream.
+//
+//=========================================================================
+
+// virtual
+sal_Int32 SAL_CALL Stream::readBytes( uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->readBytes( aData, nBytesToRead );
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL Stream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->readSomeBytes( aData, nMaxBytesToRead );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::skipBytes( sal_Int32 nBytesToSkip )
+ throw( io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedInputStream->skipBytes( nBytesToSkip );
+}
+
+//=========================================================================
+// virtual
+sal_Int32 SAL_CALL Stream::available()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ return m_xWrappedInputStream->available();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::closeInput()
+ throw( io::NotConnectedException,
+ io::IOException,
+ uno::RuntimeException )
+{
+ m_xWrappedInputStream->closeInput();
+}
+
+//=========================================================================
+//
+// lang::XComponent
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL Stream::dispose()
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->dispose();
+
+ // Release parent storage.
+ // Now, that the stream is closed/disposed it is not needed any longer.
+ setParentStorage( uno::Reference< embed::XStorage >() );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL Stream::removeEventListener(
+ const uno::Reference< lang::XEventListener >& aListener )
+ throw ( uno::RuntimeException )
+{
+ m_xWrappedComponent->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// Non-UNO
+//
+//=========================================================================
+
+void Stream::commitChanges()
+ throw( io::IOException )
+{
+ uno::Reference< embed::XTransactedObject >
+ xParentTA( getParentStorage(), uno::UNO_QUERY );
+ OSL_ENSURE( xParentTA.is(), "No XTransactedObject interface!" );
+
+ if ( xParentTA.is() )
+ {
+ try
+ {
+ xParentTA->commit();
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ throw io::IOException(); // @@@
+ }
+ }
+}
+
diff --git a/ucb/source/ucp/tdoc/tdoc_stgelems.hxx b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
new file mode 100644
index 000000000000..9afa15abf994
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_stgelems.hxx
@@ -0,0 +1,542 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_STGELEMS_HXX
+#define INCLUDED_TDOC_STGELEMS_HXX
+
+#include <memory>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implbase5.hxx"
+
+#include "com/sun/star/embed/XStorage.hpp"
+#include "com/sun/star/embed/XTransactedObject.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XStream.hpp"
+#include "com/sun/star/io/XTruncate.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+
+#include "tdoc_storage.hxx"
+
+namespace tdoc_ucp {
+
+struct MutexHolder
+{
+ osl::Mutex m_aMutex;
+};
+
+//=======================================================================
+
+class ParentStorageHolder : public MutexHolder
+{
+public:
+ ParentStorageHolder(
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri );
+
+ bool isParentARootStorage() const
+ { return m_bParentIsRootStorage; }
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ getParentStorage() const
+ { return m_xParentStorage; }
+ void setParentStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStg )
+ { osl::MutexGuard aGuard( m_aMutex ); m_xParentStorage = xStg; }
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > m_xParentStorage;
+ bool m_bParentIsRootStorage;
+};
+
+//=======================================================================
+
+typedef
+ cppu::WeakImplHelper2<
+ com::sun::star::embed::XStorage,
+ com::sun::star::embed::XTransactedObject > StorageUNOBase;
+
+class Storage : public StorageUNOBase, public ParentStorageHolder
+{
+public:
+ Storage(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< StorageElementFactory > & xFactory,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xStorageToWrap );
+ virtual ~Storage();
+
+ bool isDocumentStorage() const { return m_bIsDocumentStorage; }
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL queryInterface(
+ const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire()
+ throw ();
+ virtual void SAL_CALL release()
+ throw ();
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XComponent ( one of XStorage bases )
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener > & xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XNameAccess ( one of XStorage bases )
+ virtual com::sun::star::uno::Any SAL_CALL
+ getByName( const rtl::OUString& aName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString& aName )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XElementAccess (base of XNameAccess)
+ virtual com::sun::star::uno::Type SAL_CALL
+ getElementType()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasElements()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XStorage
+ virtual void SAL_CALL
+ copyToStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ openStreamElement( const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ openEncryptedStreamElement( const ::rtl::OUString& aStreamName,
+ sal_Int32 nOpenMode,
+ const ::rtl::OUString& aPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::NoEncryptionException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::embed::XStorage > SAL_CALL
+ openStorageElement( const ::rtl::OUString& aStorName,
+ sal_Int32 nOpenMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ cloneStreamElement( const ::rtl::OUString& aStreamName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference< com::sun::star::io::XStream > SAL_CALL
+ cloneEncryptedStreamElement( const ::rtl::OUString& aStreamName,
+ const ::rtl::OUString& aPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::packages::NoEncryptionException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyLastCommitTo( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xTargetStorage )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyStorageElementLastCommitTo( const ::rtl::OUString& aStorName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > &
+ xTargetStorage )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isStreamElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::embed::InvalidStorageException,
+ com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ isStorageElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::container::NoSuchElementException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::embed::InvalidStorageException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeElement( const ::rtl::OUString& aElementName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ renameElement( const ::rtl::OUString& aEleName,
+ const ::rtl::OUString& aNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ copyElementTo( const ::rtl::OUString& aElementName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& aNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ moveElementTo( const ::rtl::OUString& aElementName,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage >& xDest,
+ const ::rtl::OUString& rNewName )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::container::NoSuchElementException,
+ com::sun::star::container::ElementExistException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTransactedObject
+ virtual void SAL_CALL commit()
+ throw ( com::sun::star::io::IOException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL revert()
+ throw ( com::sun::star::io::IOException,
+ com::sun::star::lang::WrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+private:
+ Storage( const rtl::Reference< Storage > & rFactory ); // n.i.
+
+ rtl::Reference< StorageElementFactory > m_xFactory;
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > m_xWrappedStorage;
+ com::sun::star::uno::Reference<
+ com::sun::star::embed::XTransactedObject > m_xWrappedTransObj;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+ bool m_bIsDocumentStorage;
+
+ StorageElementFactory::StorageMap::iterator m_aContainerIt;
+
+ friend class StorageElementFactory;
+ friend class std::auto_ptr< Storage >;
+};
+
+//=======================================================================
+
+typedef
+ cppu::WeakImplHelper2<
+ com::sun::star::io::XOutputStream,
+ com::sun::star::lang::XComponent > OutputStreamUNOBase;
+
+class OutputStream : public OutputStreamUNOBase, public ParentStorageHolder
+{
+public:
+ OutputStream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > & xStreamToWrap );
+ virtual ~OutputStream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XOutputStream
+ virtual void SAL_CALL
+ writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ flush( )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ closeOutput( )
+ throw ( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XComponent
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > m_xWrappedStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+};
+
+//=======================================================================
+
+typedef cppu::WeakImplHelper5< com::sun::star::io::XStream,
+ com::sun::star::io::XOutputStream,
+ com::sun::star::io::XTruncate,
+ com::sun::star::io::XInputStream,
+ com::sun::star::lang::XComponent >
+ StreamUNOBase;
+
+class Stream : public StreamUNOBase, public ParentStorageHolder
+{
+public:
+ Stream(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::OUString & rUri,
+ const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const com::sun::star::uno::Reference<
+ com::sun::star::io::XStream > & xStreamToWrap );
+
+ virtual ~Stream();
+
+ // XInterface
+ virtual com::sun::star::uno::Any SAL_CALL
+ queryInterface( const com::sun::star::uno::Type& aType )
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XTypeProvider (implemnented by base, but needs to be overridden for
+ // delegating to aggregate)
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL
+ getTypes()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // XStream
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getInputStream()
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > SAL_CALL
+ getOutputStream()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XOutputStream
+ virtual void SAL_CALL
+ writeBytes( const com::sun::star::uno::Sequence< sal_Int8 >& aData )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ flush()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeOutput()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XTruncate
+ virtual void SAL_CALL
+ truncate()
+ throw( com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XInputStream
+ virtual sal_Int32 SAL_CALL
+ readBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ readSomeBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData,
+ sal_Int32 nMaxBytesToRead )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ skipBytes( sal_Int32 nBytesToSkip )
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::BufferSizeExceededException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int32 SAL_CALL
+ available()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL
+ closeInput()
+ throw( com::sun::star::io::NotConnectedException,
+ com::sun::star::io::IOException,
+ com::sun::star::uno::RuntimeException );
+
+ // XComponent
+ // Note: We need to intercept this one.
+ virtual void SAL_CALL
+ dispose()
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& xListener )
+ throw ( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XEventListener >& aListener )
+ throw ( com::sun::star::uno::RuntimeException );
+
+private:
+ void commitChanges()
+ throw( com::sun::star::io::IOException );
+
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XAggregation > m_xAggProxy;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XStream > m_xWrappedStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XOutputStream > m_xWrappedOutputStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XTruncate > m_xWrappedTruncate;
+ com::sun::star::uno::Reference<
+ com::sun::star::io::XInputStream > m_xWrappedInputStream;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XComponent > m_xWrappedComponent;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XTypeProvider > m_xWrappedTypeProv;
+};
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_STGELEMS_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_storage.cxx b/ucb/source/ucp/tdoc/tdoc_storage.cxx
new file mode 100644
index 000000000000..8deb942900a8
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_storage.cxx
@@ -0,0 +1,712 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ - remove root storage access workaround
+
+ *************************************************************************/
+
+#define ROOTSTORAGE_ACCESS_WORKAROUND 1
+
+#include <memory>
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/embed/ElementModes.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+
+#include "tdoc_uri.hxx"
+#include "tdoc_docmgr.hxx"
+#include "tdoc_stgelems.hxx"
+
+#include "tdoc_storage.hxx"
+
+using namespace com::sun::star;
+using namespace tdoc_ucp;
+
+
+//=========================================================================
+//=========================================================================
+//
+// StorageElementFactory Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+StorageElementFactory::StorageElementFactory(
+ const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< OfficeDocumentsManager > & xDocsMgr )
+: m_xDocsMgr( xDocsMgr ),
+ m_xSMgr( xSMgr )
+{
+}
+
+//=========================================================================
+StorageElementFactory::~StorageElementFactory()
+{
+ OSL_ENSURE( m_aMap.size() == 0,
+ "StorageElementFactory::~StorageElementFactory - Dangling storages!" );
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+StorageElementFactory::createTemporaryStorage()
+ throw ( uno::Exception,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xStorage;
+ uno::Reference< lang::XSingleServiceFactory > xStorageFac;
+ if ( m_xSMgr.is() )
+ {
+ xStorageFac = uno::Reference< lang::XSingleServiceFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.embed.StorageFactory" ) ) ),
+ uno::UNO_QUERY );
+ }
+
+ OSL_ENSURE( xStorageFac.is(), "Can't create storage factory!" );
+ if ( xStorageFac.is() )
+ xStorage = uno::Reference< embed::XStorage >(
+ xStorageFac->createInstance(),
+ uno::UNO_QUERY );
+
+ if ( !xStorage.is() )
+ throw uno::RuntimeException();
+
+ return xStorage;
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage >
+StorageElementFactory::createStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( ( eMode != READ ) &&
+ ( eMode != READ_WRITE_NOCREATE ) &&
+ ( eMode != READ_WRITE_CREATE ) )
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid open mode!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Root never has a storage!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 1 ) );
+ }
+
+ rtl::OUString aUriKey
+ ( ( rUri.getStr()[ rUri.getLength() - 1 ] == sal_Unicode( '/' ) )
+ ? rUri.copy( 0, rUri.getLength() - 1 )
+ : rUri );
+
+ StorageMap::iterator aIt ( m_aMap.begin() );
+ StorageMap::iterator aEnd( m_aMap.end() );
+
+ while ( aIt != aEnd )
+ {
+ if ( (*aIt).first.first == aUriKey )
+ {
+ // URI matches. Now, check open mode.
+ bool bMatch = true;
+ switch ( eMode )
+ {
+ case READ:
+ // No need to check; storage is at least readable.
+ bMatch = true;
+ break;
+
+ case READ_WRITE_NOCREATE:
+ case READ_WRITE_CREATE:
+ // If found storage is writable, it can be used.
+ // If not, a new one must be created.
+ bMatch = (*aIt).first.second;
+ break;
+ }
+
+ if ( bMatch )
+ break;
+ }
+ ++aIt;
+ }
+
+ if ( aIt == aEnd )
+ {
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ // documents never have a parent storage.
+ if ( !aUri.isDocument() )
+ {
+ xParentStorage = queryParentStorage( aUriKey, eMode );
+
+ if ( !xParentStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create parent storage!" );
+ return xParentStorage;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xStorage
+ = queryStorage( xParentStorage, aUriKey, eMode );
+
+ if ( !xStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create storage!" );
+ return xStorage;
+ }
+
+ bool bWritable = ( ( eMode == READ_WRITE_NOCREATE )
+ || ( eMode == READ_WRITE_CREATE ) );
+
+ std::auto_ptr< Storage > xElement(
+ new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage ) );
+
+ aIt = m_aMap.insert(
+ StorageMap::value_type(
+ std::pair< rtl::OUString, bool >( aUriKey, bWritable ),
+ xElement.get() ) ).first;
+
+ aIt->second->m_aContainerIt = aIt;
+ xElement.release();
+ return aIt->second;
+ }
+ else if ( osl_incrementInterlockedCount( &aIt->second->m_refCount ) > 1 )
+ {
+ rtl::Reference< Storage > xElement( aIt->second );
+ osl_decrementInterlockedCount( &aIt->second->m_refCount );
+ return aIt->second;
+ }
+ else
+ {
+ osl_decrementInterlockedCount( &aIt->second->m_refCount );
+ aIt->second->m_aContainerIt = m_aMap.end();
+
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ // documents never have a parent storage.
+ if ( !aUri.isDocument() )
+ {
+ xParentStorage = queryParentStorage( aUriKey, eMode );
+
+ if ( !xParentStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create parent storage!" );
+ return xParentStorage;
+ }
+ }
+
+ uno::Reference< embed::XStorage > xStorage
+ = queryStorage( xParentStorage, aUriKey, eMode );
+
+ if ( !xStorage.is() )
+ {
+ // requested to create new storage, but failed?
+ OSL_ENSURE( eMode != READ_WRITE_CREATE,
+ "Unable to create storage!" );
+ return xStorage;
+ }
+
+ aIt->second
+ = new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage );
+ aIt->second->m_aContainerIt = aIt;
+ return aIt->second;
+ }
+}
+
+//=========================================================================
+uno::Reference< io::XInputStream >
+StorageElementFactory::createInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ return uno::Reference< io::XInputStream >();
+
+ uno::Reference< io::XStream > xStream
+ = queryStream( xParentStorage, rUri, rPassword, READ, false );
+
+ if ( !xStream.is() )
+ return uno::Reference< io::XInputStream >();
+
+ return xStream->getInputStream();
+}
+
+//=========================================================================
+uno::Reference< io::XOutputStream >
+StorageElementFactory::createOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ_WRITE_CREATE );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createOutputStream - "
+ "Unable to create parent storage!" );
+ return uno::Reference< io::XOutputStream >();
+ }
+
+ uno::Reference< io::XStream > xStream
+ = queryStream(
+ xParentStorage, rUri, rPassword, READ_WRITE_CREATE, bTruncate );
+
+ if ( !xStream.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createOutputStream - "
+ "Unable to create stream!" );
+ return uno::Reference< io::XOutputStream >();
+ }
+
+ // Note: We need a wrapper to hold a reference to the parent storage to
+ // ensure that nobody else owns it at the moment we want to commit
+ // our changes. (There can be only one writable instance at a time
+ // and even no writable instance if there is already another
+ // read-only instance!)
+ return uno::Reference< io::XOutputStream >(
+ new OutputStream(
+ m_xSMgr, rUri, xParentStorage, xStream->getOutputStream() ) );
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+StorageElementFactory::createStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ uno::Reference< embed::XStorage > xParentStorage
+ = queryParentStorage( rUri, READ_WRITE_CREATE );
+
+ // Each stream must have a parent storage.
+ if ( !xParentStorage.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createStream - "
+ "Unable to create parent storage!" );
+ return uno::Reference< io::XStream >();
+ }
+
+ uno::Reference< io::XStream > xStream
+ = queryStream(
+ xParentStorage, rUri, rPassword, READ_WRITE_NOCREATE, bTruncate );
+
+ if ( !xStream.is() )
+ {
+ OSL_ENSURE( false,
+ "StorageElementFactory::createStream - "
+ "Unable to create stream!" );
+ return uno::Reference< io::XStream >();
+ }
+
+ return uno::Reference< io::XStream >(
+ new Stream( m_xSMgr, rUri, xParentStorage, xStream ) );
+}
+
+//=========================================================================
+void StorageElementFactory::releaseElement( Storage * pElement ) SAL_THROW( () )
+{
+ OSL_ASSERT( pElement );
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( pElement->m_aContainerIt != m_aMap.end() )
+ m_aMap.erase( pElement->m_aContainerIt );
+}
+
+//=========================================================================
+//
+// Non-UNO interface
+//
+//=========================================================================
+
+uno::Reference< embed::XStorage > StorageElementFactory::queryParentStorage(
+ const rtl::OUString & rUri, StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xParentStorage;
+
+ Uri aUri( rUri );
+ Uri aParentUri( aUri.getParentUri() );
+ if ( !aParentUri.isRoot() )
+ {
+ xParentStorage = createStorage( aUri.getParentUri(), eMode );
+ OSL_ENSURE( xParentStorage.is()
+ // requested to create new storage, but failed?
+ || ( eMode != READ_WRITE_CREATE ),
+ "StorageElementFactory::queryParentStorage - No storage!" );
+ }
+ return xParentStorage;
+}
+
+//=========================================================================
+uno::Reference< embed::XStorage > StorageElementFactory::queryStorage(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< embed::XStorage > xStorage;
+
+ Uri aUri( rUri );
+
+ if ( !xParentStorage.is() )
+ {
+ // document storage
+
+ xStorage = m_xDocsMgr->queryStorage( aUri.getDocumentId() );
+
+ if ( !xStorage.is() )
+ {
+ if ( eMode == READ_WRITE_CREATE )
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid open mode: document storages cannot be "
+ "created!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ else
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Invalid document id!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ // match xStorage's open mode against requested open mode
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ xStorage, uno::UNO_QUERY );
+ OSL_ENSURE( xPropSet.is(),
+ "StorageElementFactory::queryStorage - "
+ "No XPropertySet interface!" );
+ try
+ {
+ uno::Any aPropValue = xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) );
+
+ sal_Int32 nOpenMode = 0;
+ if ( aPropValue >>= nOpenMode )
+ {
+ switch ( eMode )
+ {
+ case READ:
+ if ( !( nOpenMode & embed::ElementModes::READ ) )
+ {
+ // document opened, but not readable.
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Storage is open, but not readable!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ // storage okay
+ break;
+
+ case READ_WRITE_NOCREATE:
+ case READ_WRITE_CREATE:
+ if ( !( nOpenMode & embed::ElementModes::WRITE ) )
+ {
+ // document opened, but not writable.
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Storage is open, but not writable!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ // storage okay
+ break;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(
+ false, "Bug! Value of property OpenMode has wrong type!" );
+
+ throw uno::RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Bug! Value of property OpenMode has wrong type!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+ }
+ catch ( beans::UnknownPropertyException const & e )
+ {
+ OSL_ENSURE( false, "Property OpenMode not supported!" );
+
+ throw embed::StorageWrappedTargetException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Bug! Value of property OpenMode has wrong type!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+ catch ( lang::WrappedTargetException const & e )
+ {
+ OSL_ENSURE( false, "Caught WrappedTargetException!" );
+
+ throw embed::StorageWrappedTargetException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "WrappedTargetException during getPropertyValue!" ) ),
+ uno::Reference< uno::XInterface >(),
+ uno::makeAny( e ) );
+ }
+ }
+ else
+ {
+ // sub storage
+
+ const rtl::OUString & rName = aUri.getDecodedName();
+
+ if ( eMode == READ )
+ {
+ try
+ {
+ sal_Int32 nOpenMode = embed::ElementModes::READ
+ | embed::ElementModes::NOCREATE;
+ xStorage
+ = xParentStorage->openStorageElement( rName, nOpenMode );
+ }
+ catch ( io::IOException const & )
+ {
+ // Another chance: Try to clone storage.
+ xStorage = createTemporaryStorage();
+ xParentStorage->copyStorageElementLastCommitTo( rName,
+ xStorage );
+ }
+ }
+ else
+ {
+ sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
+ if ( eMode == READ_WRITE_NOCREATE )
+ nOpenMode |= embed::ElementModes::NOCREATE;
+
+ xStorage = xParentStorage->openStorageElement( rName, nOpenMode );
+ }
+ }
+
+ OSL_ENSURE( xStorage.is() || ( eMode != READ_WRITE_CREATE ),
+ "StorageElementFactory::queryStorage - No storage!" );
+ return xStorage;
+}
+
+//=========================================================================
+uno::Reference< io::XStream >
+StorageElementFactory::queryStream(
+ const uno::Reference< embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ StorageAccessMode eMode,
+ bool bTruncate )
+ throw ( embed::InvalidStorageException,
+ lang::IllegalArgumentException,
+ io::IOException,
+ embed::StorageWrappedTargetException,
+ packages::WrongPasswordException,
+ uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !xParentStorage.is() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No parent storage!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+
+ Uri aUri( rUri );
+ if ( aUri.isRoot() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Root never is a stream!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+ else if ( aUri.isDocument() )
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "A document never is a stream!" ) ),
+ uno::Reference< uno::XInterface >(),
+ sal_Int16( 2 ) );
+ }
+
+ sal_Int32 nOpenMode;
+ switch ( eMode )
+ {
+ case READ:
+ nOpenMode = embed::ElementModes::READ
+ | embed::ElementModes::NOCREATE
+ | embed::ElementModes::SEEKABLE;
+ break;
+
+ case READ_WRITE_NOCREATE:
+ nOpenMode = embed::ElementModes::READWRITE
+ | embed::ElementModes::NOCREATE
+ | embed::ElementModes::SEEKABLE;
+
+ if ( bTruncate )
+ nOpenMode |= embed::ElementModes::TRUNCATE;
+
+ break;
+
+ case READ_WRITE_CREATE:
+ nOpenMode = embed::ElementModes::READWRITE
+ | embed::ElementModes::SEEKABLE;
+
+ if ( bTruncate )
+ nOpenMode |= embed::ElementModes::TRUNCATE;
+
+ break;
+
+ default:
+ OSL_ENSURE( false,
+ "StorageElementFactory::queryStream : Unknown open mode!" );
+
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Unknown open mode!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ // No object re-usage mechanism; streams are seekable => not stateless.
+
+ uno::Reference< io::XStream > xStream;
+ if ( rPassword.getLength() > 0 )
+ {
+ if ( eMode == READ )
+ {
+ try
+ {
+ xStream = xParentStorage->cloneEncryptedStreamElement(
+ aUri.getDecodedName(),
+ rPassword );
+ }
+ catch ( packages::NoEncryptionException const & )
+ {
+ xStream
+ = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
+ }
+ }
+ else
+ {
+ try
+ {
+ xStream = xParentStorage->openEncryptedStreamElement(
+ aUri.getDecodedName(),
+ nOpenMode,
+ rPassword );
+ }
+ catch ( packages::NoEncryptionException const & )
+ {
+ xStream
+ = xParentStorage->openStreamElement( aUri.getDecodedName(),
+ nOpenMode );
+ }
+ }
+ }
+ else
+ {
+ if ( eMode == READ )
+ {
+ xStream = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
+ }
+ else
+ {
+ xStream = xParentStorage->openStreamElement( aUri.getDecodedName(),
+ nOpenMode );
+ }
+ }
+
+ if ( !xStream.is() )
+ {
+ throw embed::InvalidStorageException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "No stream!" ) ),
+ uno::Reference< uno::XInterface >() );
+ }
+
+ return xStream;
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_storage.hxx b/ucb/source/ucp/tdoc/tdoc_storage.hxx
new file mode 100644
index 000000000000..39a95a5a7fe8
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_storage.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_STORAGE_HXX
+#define INCLUDED_TDOC_STORAGE_HXX
+
+#include <map>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "com/sun/star/embed/XStorage.hpp"
+
+namespace tdoc_ucp {
+
+ enum StorageAccessMode
+ {
+ READ, // Note: might be writable as well
+ READ_WRITE_NOCREATE,
+ READ_WRITE_CREATE
+ };
+
+ class Storage;
+ class OfficeDocumentsManager;
+
+ class StorageElementFactory : public salhelper::SimpleReferenceObject
+ {
+ public:
+ StorageElementFactory(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & xSMgr,
+ const rtl::Reference< OfficeDocumentsManager > & xDocsMgr );
+ ~StorageElementFactory();
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ createTemporaryStorage()
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ createStorage( const rtl::OUString & rUri, StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
+ createInputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >
+ createOutputStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ createStream( const rtl::OUString & rUri,
+ const rtl::OUString & rPassword,
+ bool bTruncate )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ private:
+ friend class Storage;
+
+ void releaseElement( Storage * pElement ) SAL_THROW(());
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryParentStorage( const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage >
+ queryStorage( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference< com::sun::star::io::XStream >
+ queryStream( const com::sun::star::uno::Reference<
+ com::sun::star::embed::XStorage > & xParentStorage,
+ const rtl::OUString & rPassword,
+ const rtl::OUString & rUri,
+ StorageAccessMode eMode,
+ bool bTruncate /* ignored for read-only streams */ )
+ throw ( com::sun::star::embed::InvalidStorageException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::io::IOException,
+ com::sun::star::embed::StorageWrappedTargetException,
+ com::sun::star::packages::WrongPasswordException,
+ com::sun::star::uno::RuntimeException );
+
+ struct ltstrbool
+ {
+ bool operator()(
+ const std::pair< rtl::OUString, bool > & s1,
+ const std::pair< rtl::OUString, bool > & s2 ) const
+ {
+ if ( s1.first < s2.first )
+ return true;
+ else if ( s1.first == s2.first )
+ return ( !s1.second && s2.second );
+ else
+ return false;
+ }
+ };
+
+ // key: pair< storageuri, iswritable >
+ typedef std::map<
+ std::pair< rtl::OUString, bool >, Storage *, ltstrbool > StorageMap;
+
+ StorageMap m_aMap;
+ osl::Mutex m_aMutex;
+ rtl::Reference< OfficeDocumentsManager > m_xDocsMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ };
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_STORAGE_HXX */
diff --git a/ucb/source/ucp/tdoc/tdoc_uri.cxx b/ucb/source/ucp/tdoc/tdoc_uri.cxx
new file mode 100644
index 000000000000..712ced2d04f1
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_uri.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+/**************************************************************************
+ TODO
+ **************************************************************************
+
+ *************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+#include "../inc/urihelper.hxx"
+
+#include "tdoc_uri.hxx"
+
+using namespace tdoc_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// Uri Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+void Uri::init() const
+{
+ // Already inited?
+ if ( m_eState == UNKNOWN )
+ {
+ m_eState = INVALID;
+
+ // Check for proper length: must be at least length of <sheme>:/
+ if ( ( m_aUri.getLength() < TDOC_URL_SCHEME_LENGTH + 2 ) )
+ {
+ // Invaild length (to short).
+ return;
+ }
+
+ // Check for proper scheme. (Scheme is case insensitive.)
+ rtl::OUString aScheme
+ = m_aUri.copy( 0, TDOC_URL_SCHEME_LENGTH ).toAsciiLowerCase();
+ if ( !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( TDOC_URL_SCHEME ) ) )
+ {
+ // Invaild scheme.
+ return;
+ }
+
+ // Remember normalized scheme string.
+ m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme );
+
+ if ( m_aUri.getStr()[ TDOC_URL_SCHEME_LENGTH ]
+ != sal_Unicode( ':' ) )
+ {
+ // Invaild (no ':' after <scheme>).
+ return;
+ }
+
+ if ( m_aUri.getStr()[ TDOC_URL_SCHEME_LENGTH + 1 ]
+ != sal_Unicode( '/' ) )
+ {
+ // Invaild (no '/' after <scheme>:).
+ return;
+ }
+
+ m_aPath = m_aUri.copy( TDOC_URL_SCHEME_LENGTH + 1 );
+
+ // Note: There must be at least one slash; see above.
+ sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' );
+ bool bTrailingSlash = false;
+ if ( nLastSlash == m_aUri.getLength() - 1 )
+ {
+ // ignore trailing slash
+ bTrailingSlash = true;
+ nLastSlash = m_aUri.lastIndexOf( '/', nLastSlash );
+ }
+
+ if ( nLastSlash != -1 ) // -1 is valid for the root folder
+ {
+ m_aParentUri = m_aUri.copy( 0, nLastSlash + 1 );
+
+ if ( bTrailingSlash )
+ m_aName = m_aUri.copy( nLastSlash + 1,
+ m_aUri.getLength() - nLastSlash - 2 );
+ else
+ m_aName = m_aUri.copy( nLastSlash + 1 );
+
+ m_aDecodedName = ::ucb_impl::urihelper::decodeSegment( m_aName );
+
+ sal_Int32 nSlash = m_aPath.indexOf( '/', 1 );
+ if ( nSlash == -1 )
+ m_aDocId = m_aPath.copy( 1 );
+ else
+ m_aDocId = m_aPath.copy( 1, nSlash - 1 );
+ }
+
+ if ( m_aDocId.getLength() > 0 )
+ {
+ sal_Int32 nSlash = m_aPath.indexOf( '/', 1 );
+ if ( nSlash != - 1 )
+ m_aInternalPath = m_aPath.copy( nSlash );
+ else
+ m_aInternalPath = rtl::OUString::createFromAscii( "/" );
+ }
+
+ m_eState = VALID;
+ }
+}
diff --git a/ucb/source/ucp/tdoc/tdoc_uri.hxx b/ucb/source/ucp/tdoc/tdoc_uri.hxx
new file mode 100644
index 000000000000..5f251cc55bee
--- /dev/null
+++ b/ucb/source/ucp/tdoc/tdoc_uri.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_TDOC_URI_HXX
+#define INCLUDED_TDOC_URI_HXX
+
+#include "rtl/ustring.hxx"
+
+namespace tdoc_ucp {
+
+//=========================================================================
+
+#define TDOC_URL_SCHEME "vnd.sun.star.tdoc"
+#define TDOC_URL_SCHEME_LENGTH 17
+
+//=========================================================================
+
+class Uri
+{
+ enum State { UNKNOWN, INVALID, VALID };
+
+ mutable ::rtl::OUString m_aUri;
+ mutable ::rtl::OUString m_aParentUri;
+ mutable ::rtl::OUString m_aPath;
+ mutable ::rtl::OUString m_aDocId;
+ mutable ::rtl::OUString m_aInternalPath;
+ mutable ::rtl::OUString m_aName;
+ mutable ::rtl::OUString m_aDecodedName;
+ mutable State m_eState;
+
+private:
+ void init() const;
+
+public:
+ Uri() : m_eState( UNKNOWN ) {}
+ Uri( const ::rtl::OUString & rUri )
+ : m_aUri( rUri ), m_eState( UNKNOWN ) {}
+
+ bool operator== ( const Uri & rOther ) const
+ { init(); return m_aUri == rOther.m_aUri; }
+
+ bool operator!= ( const Uri & rOther ) const
+ { return !operator==( rOther ); }
+
+ sal_Bool isValid() const
+ { init(); return m_eState == VALID; }
+
+ const ::rtl::OUString & getUri() const
+ { init(); return m_aUri; }
+
+ inline void setUri( const ::rtl::OUString & rUri );
+
+ const ::rtl::OUString & getParentUri() const
+ { init(); return m_aParentUri; }
+
+ const ::rtl::OUString & getPath() const
+ { init(); return m_aPath; }
+
+ const ::rtl::OUString & getDocumentId() const
+ { init(); return m_aDocId; }
+
+ const ::rtl::OUString & getInternalPath() const
+ { init(); return m_aInternalPath; }
+
+ const ::rtl::OUString & getName() const
+ { init(); return m_aName; }
+
+ const ::rtl::OUString & getDecodedName() const
+ { init(); return m_aDecodedName; }
+
+ inline sal_Bool isRoot() const;
+
+ inline sal_Bool isDocument() const;
+
+ inline sal_Bool isFolder() const;
+};
+
+inline void Uri::setUri( const ::rtl::OUString & rUri )
+{
+ m_eState = UNKNOWN;
+ m_aUri = rUri;
+ m_aParentUri = m_aDocId = m_aInternalPath = m_aPath = m_aName
+ = m_aDecodedName = rtl::OUString();
+}
+
+inline sal_Bool Uri::isRoot() const
+{
+ init();
+ return ( m_aPath.getLength() == 1 );
+}
+
+inline sal_Bool Uri::isDocument() const
+{
+ init();
+ return ( ( m_aDocId.getLength() > 0 ) /* not root */
+ && ( m_aPath.copy( m_aDocId.getLength() + 1 ).getLength() < 2 ) );
+}
+
+inline sal_Bool Uri::isFolder() const
+{
+ init();
+ return ( m_aPath.lastIndexOf( '/' ) == m_aPath.getLength() - 1 );
+}
+
+} // namespace tdoc_ucp
+
+#endif /* !INCLUDED_TDOC_URI_HXX */
diff --git a/ucb/source/ucp/tdoc/ucptdoc.xml b/ucb/source/ucp/tdoc/ucptdoc.xml
new file mode 100644
index 000000000000..b47249269470
--- /dev/null
+++ b/ucb/source/ucp/tdoc/ucptdoc.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ ucptdoc
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.TransientDocumentsContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal Content Broker.
+ It provides access to the hierachical structure of the documents that are active
+ in a running OpenOffice.org process.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.TransientDocumentsContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.frame.GlobalEventBroadcaster
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.reflection.ProxyFactory
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.embed.StorageFactory
+ </service-dependency>
+ </component-description>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.TransientDocumentsDocumentContentFactory
+ </name>
+ <description>
+ This component implements a factory for
+ 'com.sun.star.ucb.TransientDocumentsDocumentContent's.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.frame.TransientDocumentsDocumentContentFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.TransientDocumentsContentProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.Property </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.document.XStorageBasedDocument </type>
+ <type> com.sun.star.document.XEventBroadcaster </type>
+ <type> com.sun.star.document.XEventListener </type>
+ <type> com.sun.star.embed.ElementModes </type>
+ <type> com.sun.star.embed.XStorage </type>
+ <type> com.sun.star.embed.XTransactedObject </type>
+ <type> com.sun.star.frame.XTransientDocumentsDocumentContentFactory </type>
+ <type> com.sun.star.io.XActiveDataSink </type>
+ <type> com.sun.star.io.XActiveDataStreamer </type>
+ <type> com.sun.star.io.XSeekable </type>
+ <type> com.sun.star.io.XTruncate </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.reflection.XProxyFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.task.DocumentPasswordRequest </type>
+ <type> com.sun.star.task.XInteractionPassword </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.CommandInfo </type>
+ <type> com.sun.star.ucb.ContentInfoAttribute </type>
+ <type> com.sun.star.ucb.InsertCommandArgument </type>
+ <type> com.sun.star.ucb.InteractiveBadTransferURLException </type>
+ <type> com.sun.star.ucb.MissingInputStreamException </type>
+ <type> com.sun.star.ucb.MissingPropertiesException </type>
+ <type> com.sun.star.ucb.NameClash </type>
+ <type> com.sun.star.ucb.NameClashException </type>
+ <type> com.sun.star.ucb.OpenCommandArgument2 </type>
+ <type> com.sun.star.ucb.OpenMode </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsupportedCommandException </type>
+ <type> com.sun.star.ucb.UnsupportedDataSinkException </type>
+ <type> com.sun.star.ucb.UnsupportedNameClashException </type>
+ <type> com.sun.star.ucb.UnsupportedOpenModeException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XAggregation </type>
+
+</module-description>