summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/hierarchy
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/hierarchy')
-rw-r--r--ucb/source/ucp/hierarchy/dynamicresultset.cxx91
-rw-r--r--ucb/source/ucp/hierarchy/dynamicresultset.hxx55
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontent.cxx2009
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontent.hxx311
-rw-r--r--ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx765
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydata.cxx1266
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydata.hxx149
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasource.cxx1116
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasource.hxx125
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx446
-rw-r--r--ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx82
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyprovider.cxx338
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyprovider.hxx155
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyservices.cxx149
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyuri.cxx209
-rw-r--r--ucb/source/ucp/hierarchy/hierarchyuri.hxx91
-rw-r--r--ucb/source/ucp/hierarchy/makefile.mk84
-rw-r--r--ucb/source/ucp/hierarchy/ucphier.xml121
18 files changed, 7562 insertions, 0 deletions
diff --git a/ucb/source/ucp/hierarchy/dynamicresultset.cxx b/ucb/source/ucp/hierarchy/dynamicresultset.cxx
new file mode 100644
index 000000000000..0cb8fec28e17
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/dynamicresultset.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * 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 "hierarchydatasupplier.hxx"
+#include "dynamicresultset.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// DynamicResultSet Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+DynamicResultSet::DynamicResultSet(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& 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 HierarchyResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+}
+
+//=========================================================================
+void DynamicResultSet::initDynamic()
+{
+ m_xResultSet1
+ = new ::ucbhelper::ResultSet(
+ m_xSMgr,
+ m_aCommand.Properties,
+ new HierarchyResultSetDataSupplier( m_xSMgr,
+ m_xContent,
+ m_aCommand.Mode ) );
+ m_xResultSet2 = m_xResultSet1;
+}
+
diff --git a/ucb/source/ucp/hierarchy/dynamicresultset.hxx b/ucb/source/ucp/hierarchy/dynamicresultset.hxx
new file mode 100644
index 000000000000..9553b299b0ad
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/dynamicresultset.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * 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 _DYNAMICRESULTSET_HXX
+#define _DYNAMICRESULTSET_HXX
+
+#include <rtl/ref.hxx>
+#include <ucbhelper/resultsethelper.hxx>
+#include "hierarchycontent.hxx"
+
+namespace hierarchy_ucp {
+
+class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+{
+ rtl::Reference< HierarchyContent > 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< HierarchyContent >& rxContent,
+ const com::sun::star::ucb::OpenCommandArgument2& rCommand );
+};
+
+}
+
+#endif /* !_DYNAMICRESULTSET_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchycontent.cxx b/ucb/source/ucp/hierarchy/hierarchycontent.cxx
new file mode 100644
index 000000000000..2243692549e6
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontent.cxx
@@ -0,0 +1,2009 @@
+/*************************************************************************
+ *
+ * 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
+ **************************************************************************
+
+ - optimize transfer command. "Move" should be implementable much more
+ efficient!
+
+ **************************************************************************
+
+ - Root Folder vs. 'normal' Folder
+ - root doesn't support command 'delete'
+ - root doesn't support command 'insert'
+ - root needs not created via XContentCreator - queryContent with root
+ folder id ( HIERARCHY_ROOT_FOLDER_URL ) always returns a value != 0
+ - root has no parent.
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.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/TransferInfo.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/cancelcommandexecution.hxx>
+#include "hierarchycontent.hxx"
+#include "hierarchyprovider.hxx"
+#include "dynamicresultset.hxx"
+#include "hierarchyuri.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContent Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static ( "virtual" ctor )
+HierarchyContent* HierarchyContent::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ // Fail, if content does not exist.
+ HierarchyContentProperties aProps;
+ if ( !loadData( rxSMgr, pProvider, Identifier, aProps ) )
+ return 0;
+
+ return new HierarchyContent( rxSMgr, pProvider, Identifier, aProps );
+}
+
+//=========================================================================
+// static ( "virtual" ctor )
+HierarchyContent* HierarchyContent::create(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+{
+ if ( !Info.Type.getLength() )
+ return 0;
+
+ if ( !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_FOLDER_CONTENT_TYPE ) ) &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_LINK_CONTENT_TYPE ) ) )
+ return 0;
+
+#if 0
+ // Fail, if content does exist.
+ if ( hasData( rxSMgr, pProvider, Identifier ) )
+ return 0;
+#endif
+
+ return new HierarchyContent( rxSMgr, pProvider, Identifier, Info );
+}
+
+//=========================================================================
+HierarchyContent::HierarchyContent(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const HierarchyContentProperties& rProps )
+: ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( rProps ),
+ m_eState( PERSISTENT ),
+ m_pProvider( pProvider ),
+ m_bCheckedReadOnly( false ),
+ m_bIsReadOnly( true )
+{
+ setKind( Identifier );
+}
+
+//=========================================================================
+HierarchyContent::HierarchyContent(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ const ucb::ContentInfo& Info )
+ : ContentImplHelper( rxSMgr, pProvider, Identifier ),
+ m_aProps( Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_FOLDER_CONTENT_TYPE ) )
+ ? HierarchyEntryData::FOLDER
+ : HierarchyEntryData::LINK ),
+ m_eState( TRANSIENT ),
+ m_pProvider( pProvider ),
+ m_bCheckedReadOnly( false ),
+ m_bIsReadOnly( true )
+{
+ setKind( Identifier );
+}
+
+//=========================================================================
+// virtual
+HierarchyContent::~HierarchyContent()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyContent::acquire()
+ throw( )
+{
+ ContentImplHelper::acquire();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyContent::release()
+ throw( )
+{
+ ContentImplHelper::release();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL HierarchyContent::queryInterface( const uno::Type & rType )
+ throw ( uno::RuntimeException )
+{
+ uno::Any aRet = ContentImplHelper::queryInterface( rType );
+
+ if ( !aRet.hasValue() )
+ {
+ // Note: isReadOnly may be relative expensive. So avoid calling it
+ // unless it is really necessary.
+ aRet = cppu::queryInterface(
+ rType, static_cast< ucb::XContentCreator * >( this ) );
+ if ( aRet.hasValue() )
+ {
+ if ( !isFolder() || isReadOnly() )
+ return uno::Any();
+ }
+ }
+
+ return aRet;
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( HierarchyContent );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL HierarchyContent::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( isFolder() && !isReadOnly() )
+ {
+ 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 HierarchyContent::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyContent" );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL
+HierarchyContent::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aSNS( 1 );
+
+ if ( m_eKind == LINK )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_LINK_CONTENT_SERVICE_NAME );
+ else if ( m_eKind == FOLDER )
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_FOLDER_CONTENT_SERVICE_NAME );
+ else
+ aSNS.getArray()[ 0 ] = rtl::OUString::createFromAscii(
+ HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME );
+
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XContent methods.
+//
+//=========================================================================
+
+// virtual
+rtl::OUString SAL_CALL HierarchyContent::getContentType()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getContentType();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier > SAL_CALL
+HierarchyContent::getIdentifier()
+ throw( uno::RuntimeException )
+{
+ // 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 HierarchyContent::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" ) ) && isFolder() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // open command for a folder content
+ //////////////////////////////////////////////////////////////////
+
+ 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
+ }
+
+ uno::Reference< ucb::XDynamicResultSet > xSet
+ = new DynamicResultSet( m_xSMgr, this, aOpenCommand );
+ aRet <<= xSet;
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "insert" ) ) &&
+ ( m_eKind != ROOT ) && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // insert
+ // ( Not available at root folder )
+ //////////////////////////////////////////////////////////////////
+
+ 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( nNameClash, Environment );
+ }
+ else if ( aCommand.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "delete" ) ) &&
+ ( m_eKind != ROOT ) && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // delete
+ // ( Not available at root folder )
+ //////////////////////////////////////////////////////////////////
+
+ 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" ) ) &&
+ isFolder() && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // transfer
+ // ( Not available at link objects )
+ //////////////////////////////////////////////////////////////////
+
+ 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" ) ) &&
+ isFolder() && !isReadOnly() )
+ {
+ //////////////////////////////////////////////////////////////////
+ // createNewContent
+ // ( Not available at link objects )
+ //////////////////////////////////////////////////////////////////
+
+ 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 HierarchyContent::abort( sal_Int32 /*CommandId*/ )
+ throw( uno::RuntimeException )
+{
+ // @@@ Generally, no action takes much time...
+}
+
+//=========================================================================
+//
+// XContentCreator methods.
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< ucb::ContentInfo > SAL_CALL
+HierarchyContent::queryCreatableContentsInfo()
+ throw( uno::RuntimeException )
+{
+ return m_aProps.getCreatableContentsInfo();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+HierarchyContent::createNewContent( const ucb::ContentInfo& Info )
+ throw( uno::RuntimeException )
+{
+ if ( isFolder() )
+ {
+ 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( HIERARCHY_FOLDER_CONTENT_TYPE ) );
+
+ if ( !bCreateFolder &&
+ !Info.Type.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_LINK_CONTENT_TYPE ) ) )
+ return uno::Reference< ucb::XContent >();
+
+ rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
+
+ OSL_ENSURE( aURL.getLength() > 0,
+ "HierarchyContent::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_Link" );
+
+ 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-folder object!" );
+ return uno::Reference< ucb::XContent >();
+ }
+}
+
+//=========================================================================
+// virtual
+rtl::OUString HierarchyContent::getParentURL()
+{
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ return aUri.getParentUri();
+}
+
+//=========================================================================
+//static
+sal_Bool HierarchyContent::hasData(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+
+ // Am I a root folder?
+ HierarchyUri aUri( aURL );
+ if ( aUri.isRootFolder() )
+ {
+ // hasData must always return 'true' for root folder
+ // even if no persistent data exist!!!
+ return sal_True;
+ }
+
+ return HierarchyEntry( rxSMgr, pProvider, aURL ).hasData();
+}
+
+//=========================================================================
+//static
+sal_Bool HierarchyContent::loadData(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const uno::Reference< ucb::XContentIdentifier >& Identifier,
+ HierarchyContentProperties& rProps )
+{
+ rtl::OUString aURL = Identifier->getContentIdentifier();
+
+ // Am I a root folder?
+ HierarchyUri aUri( aURL );
+ if ( aUri.isRootFolder() )
+ {
+ rProps = HierarchyContentProperties( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ HierarchyEntry aEntry( rxSMgr, pProvider, aURL );
+ HierarchyEntryData aData;
+ if ( !aEntry.getData( aData ) )
+ return sal_False;
+
+ rProps = HierarchyContentProperties( aData );
+ }
+ return sal_True;
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::storeData()
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
+ return aEntry.setData( m_aProps.getHierarchyEntryData(), sal_True );
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::renameData(
+ const uno::Reference< ucb::XContentIdentifier >& xOldId,
+ const uno::Reference< ucb::XContentIdentifier >& xNewId )
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, xOldId->getContentIdentifier() );
+ return aEntry.move( xNewId->getContentIdentifier(),
+ m_aProps.getHierarchyEntryData() );
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::removeData()
+{
+ HierarchyEntry aEntry(
+ m_xSMgr, m_pProvider, m_xIdentifier->getContentIdentifier() );
+ return aEntry.remove();
+}
+
+//=========================================================================
+void HierarchyContent::setKind(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+{
+ if ( m_aProps.getIsFolder() )
+ {
+ // Am I a root folder?
+ HierarchyUri aUri( Identifier->getContentIdentifier() );
+ if ( aUri.isRootFolder() )
+ m_eKind = ROOT;
+ else
+ m_eKind = FOLDER;
+ }
+ else
+ m_eKind = LINK;
+}
+
+//=========================================================================
+bool HierarchyContent::isReadOnly()
+{
+ if ( !m_bCheckedReadOnly )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_bCheckedReadOnly )
+ {
+ m_bCheckedReadOnly = true;
+ m_bIsReadOnly = true;
+
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv
+ = m_pProvider->getConfigProvider( aUri.getService() );
+ if ( xConfigProv.is() )
+ {
+ uno::Sequence< rtl::OUString > aNames
+ = xConfigProv->getAvailableServiceNames();
+ sal_Int32 nCount = aNames.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ if ( aNames[ n ].equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+ ) ) )
+ {
+ m_bIsReadOnly = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return m_bIsReadOnly;
+}
+
+//=========================================================================
+uno::Reference< ucb::XContentIdentifier >
+HierarchyContent::makeNewIdentifier( const rtl::OUString& rTitle )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Assemble new content identifier...
+ HierarchyUri aUri( m_xIdentifier->getContentIdentifier() );
+ rtl::OUString aNewURL = aUri.getParentUri();
+ aNewURL += rtl::OUString::createFromAscii( "/" );
+ aNewURL += ::ucb_impl::urihelper::encodeSegment( rTitle );
+
+ return uno::Reference< ucb::XContentIdentifier >(
+ new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL ) );
+}
+
+//=========================================================================
+void HierarchyContent::queryChildren( HierarchyContentRefList& rChildren )
+{
+ if ( ( m_eKind != FOLDER ) && ( m_eKind != ROOT ) )
+ 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(
+ HierarchyContentRef(
+ static_cast< HierarchyContent * >( xChild.get() ) ) );
+ }
+ }
+ ++it;
+ }
+}
+
+//=========================================================================
+sal_Bool HierarchyContent::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,
+ "HierarchyContent::exchangeIdentity - Not persistent!" );
+ return sal_False;
+ }
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ OSL_ENSURE( sal_False, "HierarchyContent::exchangeIdentity - "
+ "Not supported by root folder!" );
+ return sal_False;
+ }
+
+ // Exchange own identitity.
+
+ // Fail, if a content with given id already exists.
+ if ( !hasData( xNewId ) )
+ {
+ rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier();
+
+ aGuard.clear();
+ if ( exchange( xNewId ) )
+ {
+ if ( m_eKind == FOLDER )
+ {
+ // Process instanciated children...
+
+ HierarchyContentRefList aChildren;
+ queryChildren( aChildren );
+
+ HierarchyContentRefList::const_iterator it = aChildren.begin();
+ HierarchyContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ HierarchyContentRef 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,
+ "HierarchyContent::exchangeIdentity - "
+ "Panic! Cannot exchange identity!" );
+ return sal_False;
+}
+
+//=========================================================================
+// static
+uno::Reference< sdbc::XRow > HierarchyContent::getPropertyValues(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ const uno::Sequence< beans::Property >& rProperties,
+ const HierarchyContentProperties& rData,
+ HierarchyContentProvider* 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( "TargetURL" ) ) )
+ {
+ // TargetURL is only supported by links.
+
+ if ( rData.getIsDocument() )
+ xRow->appendString( rProp, rData.getTargetURL() );
+ 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() );
+ xRow->appendString (
+ beans::Property( rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ // @@@ Might actually be read-only!
+ beans::PropertyAttribute::BOUND ),
+ 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() );
+
+ if ( rData.getIsDocument() )
+ xRow->appendString(
+ beans::Property( rtl::OUString::createFromAscii( "TargetURL" ),
+ -1,
+ getCppuType(
+ static_cast< const rtl::OUString * >( 0 ) ),
+ // @@@ Might actually be read-only!
+ beans::PropertyAttribute::BOUND ),
+ rData.getTargetURL() );
+ 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() ) );
+
+ // 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 > HierarchyContent::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 > HierarchyContent::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;
+ rtl::OUString aOldName;
+ 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" ) ) )
+ {
+ if ( isReadOnly() )
+ {
+ 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();
+ aOldName = m_aProps.getName();
+
+ m_aProps.setTitle( aNewValue );
+ m_aProps.setName(
+ ::ucb_impl::urihelper::encodeSegment(
+ aNewValue ) );
+
+ // property change event will be set 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(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ }
+ else if ( rValue.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "TargetURL" ) ) )
+ {
+ if ( isReadOnly() )
+ {
+ aRet[ n ] <<= lang::IllegalAccessException(
+ rtl::OUString::createFromAscii(
+ "Property is read-only!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ else
+ {
+ // TargetURL is only supported by links.
+
+ if ( m_eKind == LINK )
+ {
+ rtl::OUString aNewValue;
+ if ( rValue.Value >>= aNewValue )
+ {
+ // No empty target URL's!
+ if ( aNewValue.getLength() > 0 )
+ {
+ if ( aNewValue != m_aProps.getTargetURL() )
+ {
+ aEvent.PropertyName = rValue.Name;
+ aEvent.OldValue
+ = uno::makeAny( m_aProps.getTargetURL() );
+ aEvent.NewValue
+ = uno::makeAny( aNewValue );
+
+ aChanges.getArray()[ nChanged ] = aEvent;
+
+ m_aProps.setTargetURL( aNewValue );
+ nChanged++;
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= lang::IllegalArgumentException(
+ rtl::OUString::createFromAscii(
+ "Empty target URL not allowed!" ),
+ static_cast< cppu::OWeakObject * >( this ),
+ -1 );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::IllegalTypeException(
+ rtl::OUString::createFromAscii(
+ "Property value has wrong type!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+ }
+ else
+ {
+ aRet[ n ] <<= beans::UnknownPropertyException(
+ rtl::OUString::createFromAscii(
+ "TargetURL only supported by links!" ),
+ 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 );
+ m_aProps.setName ( aOldName );
+
+ aOldTitle = aOldName = 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::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;
+}
+
+//=========================================================================
+void HierarchyContent::insert( sal_Int32 nNameClashResolve,
+ const uno::Reference<
+ ucb::XCommandEnvironment > & xEnv )
+ throw( uno::Exception )
+{
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not supported by root folder!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Check, if all required properties were set.
+ if ( m_aProps.getTitle().getLength() == 0 )
+ {
+ uno::Sequence< rtl::OUString > aProps( 1 );
+ aProps[ 0 ] = rtl::OUString::createFromAscii( "Title" );
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::MissingPropertiesException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ aProps ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ // Assemble new content identifier...
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = makeNewIdentifier( m_aProps.getTitle() );
+
+ // Handle possible name clash...
+
+ switch ( nNameClashResolve )
+ {
+ // fail.
+ case ucb::NameClash::ERROR:
+ if ( hasData( xId ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::NameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ task::InteractionClassification_ERROR,
+ m_aProps.getTitle() ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+
+ // replace existing object.
+ case ucb::NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case ucb::NameClash::RENAME:
+ if ( hasData( xId ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ rtl::OUString aNewId = xId->getContentIdentifier();
+ aNewId += rtl::OUString::createFromAscii( "_" );
+ aNewId += rtl::OUString::valueOf( ++nTry );
+ xId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewId );
+ }
+ while ( hasData( xId ) && ( 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::OUString aNewTitle( m_aProps.getTitle() );
+ aNewTitle += rtl::OUString::createFromAscii( "_" );
+ aNewTitle += rtl::OUString::valueOf( nTry );
+ m_aProps.setTitle( aNewTitle );
+ }
+ }
+ break;
+
+ case ucb::NameClash::KEEP: // deprecated
+ case ucb::NameClash::ASK:
+ default:
+ if ( hasData( xId ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny(
+ ucb::UnsupportedNameClashException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ),
+ nNameClashResolve ) ),
+ xEnv );
+ // Unreachable
+ }
+ break;
+ }
+
+ // Identifier changed?
+ sal_Bool bNewId = ( xId->getContentIdentifier()
+ != m_xIdentifier->getContentIdentifier() );
+ m_xIdentifier = xId;
+
+ if ( !storeData() )
+ {
+ 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 )
+ {
+ aGuard.clear();
+ inserted();
+ }
+}
+
+//=========================================================================
+void HierarchyContent::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 );
+
+ 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
+ }
+
+ // Am I the root folder?
+ if ( m_eKind == ROOT )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::UnsupportedCommandException(
+ rtl::OUString::createFromAscii(
+ "Not supported by root folder!" ),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ xEnv );
+ // Unreachable
+ }
+
+ m_eState = DEAD;
+
+ aGuard.clear();
+ deleted();
+
+ if ( m_eKind == FOLDER )
+ {
+ // Process instanciated children...
+
+ HierarchyContentRefList aChildren;
+ queryChildren( aChildren );
+
+ HierarchyContentRefList::const_iterator it = aChildren.begin();
+ HierarchyContentRefList::const_iterator end = aChildren.end();
+
+ while ( it != end )
+ {
+ (*it)->destroy( bDeletePhysical, xEnv );
+ ++it;
+ }
+ }
+}
+
+//=========================================================================
+void HierarchyContent::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
+ }
+
+ // Is source a hierarchy content?
+ if ( ( rInfo.SourceURL.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 2 ) ||
+ ( rInfo.SourceURL.compareToAscii( HIERARCHY_URL_SCHEME ":/",
+ HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ != 0 ) )
+ {
+ ucbhelper::cancelCommandExecution(
+ uno::makeAny( ucb::InteractiveBadTransferURLException(
+ rtl::OUString(),
+ static_cast< cppu::OWeakObject * >( this ) ) ),
+ 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
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 0) Obtain content object for source.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Reference< ucb::XContentIdentifier > xId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the HierarchyContentProvider.
+ rtl::Reference< HierarchyContent > xSource;
+
+ try
+ {
+ xSource = static_cast< HierarchyContent * >(
+ m_xProvider->queryContent( xId ).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(xId->getContentIdentifier()),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_READ,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "Cannot instanciate source object!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 1) Create new child content.
+ //////////////////////////////////////////////////////////////////////
+
+ rtl::OUString aType = xSource->isFolder()
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE );
+ ucb::ContentInfo aContentInfo;
+ aContentInfo.Type = aType;
+ aContentInfo.Attributes = 0;
+
+ // Note: The static cast is okay here, because its sure that
+ // createNewContent always creates a HierarchyContent.
+ rtl::Reference< HierarchyContent > xTarget
+ = static_cast< HierarchyContent * >(
+ createNewContent( aContentInfo ).get() );
+ if ( !xTarget.is() )
+ {
+ uno::Any aProps
+ = uno::makeAny(beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Folder")),
+ -1,
+ uno::makeAny(aId),
+ beans::PropertyState_DIRECT_VALUE));
+ ucbhelper::cancelCommandExecution(
+ ucb::IOErrorCode_CANT_CREATE,
+ uno::Sequence< uno::Any >(&aProps, 1),
+ xEnv,
+ rtl::OUString::createFromAscii(
+ "XContentCreator::createNewContent failed!" ),
+ this );
+ // Unreachable
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 2) Copy data from source content to child content.
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Sequence< beans::Property > aSourceProps
+ = xSource->getPropertySetInfo( xEnv )->getProperties();
+ sal_Int32 nCount = aSourceProps.getLength();
+
+ if ( nCount )
+ {
+ sal_Bool bHadTitle = ( rInfo.NewTitle.getLength() == 0 );
+
+ // Get all source values.
+ uno::Reference< sdbc::XRow > xRow
+ = xSource->getPropertyValues( aSourceProps );
+
+ uno::Sequence< beans::PropertyValue > aValues( nCount );
+ beans::PropertyValue* pValues = aValues.getArray();
+
+ const beans::Property* pProps = aSourceProps.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const beans::Property& rProp = pProps[ n ];
+ beans::PropertyValue& rValue = pValues[ n ];
+
+ rValue.Name = rProp.Name;
+ rValue.Handle = rProp.Handle;
+
+ if ( !bHadTitle && rProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
+ {
+ // Set new title instead of original.
+ bHadTitle = sal_True;
+ rValue.Value <<= rInfo.NewTitle;
+ }
+ else
+ rValue.Value = xRow->getObject(
+ n + 1,
+ uno::Reference< container::XNameAccess >() );
+
+ rValue.State = beans::PropertyState_DIRECT_VALUE;
+
+ if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
+ {
+ // Add Additional Core Property.
+ try
+ {
+ xTarget->addProperty( rProp.Name,
+ rProp.Attributes,
+ rValue.Value );
+ }
+ catch ( beans::PropertyExistException const & )
+ {
+ }
+ catch ( beans::IllegalTypeException const & )
+ {
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ }
+ }
+ }
+
+ // Set target values.
+ xTarget->setPropertyValues( aValues, xEnv );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 3) Commit (insert) child.
+ //////////////////////////////////////////////////////////////////////
+
+ xTarget->insert( rInfo.NameClash, xEnv );
+
+ //////////////////////////////////////////////////////////////////////
+ // 4) Transfer (copy) children of source.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xSource->isFolder() )
+ {
+ HierarchyEntry aFolder(
+ m_xSMgr, m_pProvider, xId->getContentIdentifier() );
+ HierarchyEntry::iterator it;
+
+ while ( aFolder.next( it ) )
+ {
+ const HierarchyEntryData& rResult = *it;
+
+ rtl::OUString aChildId = xId->getContentIdentifier();
+ if ( ( aChildId.lastIndexOf( '/' ) + 1 ) != aChildId.getLength() )
+ aChildId += rtl::OUString::createFromAscii( "/" );
+
+ aChildId += rResult.getName();
+
+ ucb::TransferInfo aInfo;
+ aInfo.MoveData = sal_False;
+ aInfo.NewTitle = rtl::OUString();
+ aInfo.SourceURL = aChildId;
+ aInfo.NameClash = rInfo.NameClash;
+
+ // Transfer child to target.
+ xTarget->transfer( aInfo, xEnv );
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // 5) Destroy source ( when moving only ) .
+ //////////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ 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(
+ xSource->m_xIdentifier->
+ getContentIdentifier()),
+ 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.
+ xSource->removeAdditionalPropertySet( sal_True );
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContentProperties Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+uno::Sequence< ucb::ContentInfo >
+HierarchyContentProperties::getCreatableContentsInfo() const
+{
+ if ( getIsFolder() )
+ {
+ uno::Sequence< ucb::ContentInfo > aSeq( 2 );
+
+ // Folder.
+ aSeq.getArray()[ 0 ].Type
+ = rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE );
+ aSeq.getArray()[ 0 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_FOLDER;
+
+ uno::Sequence< beans::Property > aFolderProps( 1 );
+ aFolderProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aSeq.getArray()[ 0 ].Properties = aFolderProps;
+
+ // Link.
+ aSeq.getArray()[ 1 ].Type
+ = rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE );
+ aSeq.getArray()[ 1 ].Attributes
+ = ucb::ContentInfoAttribute::KIND_LINK;
+
+ uno::Sequence< beans::Property > aLinkProps( 2 );
+ aLinkProps.getArray()[ 0 ] = beans::Property(
+ rtl::OUString::createFromAscii( "Title" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aLinkProps.getArray()[ 1 ] = beans::Property(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND );
+ aSeq.getArray()[ 1 ].Properties = aLinkProps;
+
+ return aSeq;
+ }
+ else
+ {
+ return uno::Sequence< ucb::ContentInfo >( 0 );
+ }
+}
diff --git a/ucb/source/ucp/hierarchy/hierarchycontent.hxx b/ucb/source/ucp/hierarchy/hierarchycontent.hxx
new file mode 100644
index 000000000000..5b7360a87719
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontent.hxx
@@ -0,0 +1,311 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYCONTENT_HXX
+#define _HIERARCHYCONTENT_HXX
+
+#include <list>
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/XContentCreator.hpp>
+#include <ucbhelper/contenthelper.hxx>
+#include "hierarchydata.hxx"
+#include "hierarchyprovider.hxx"
+
+namespace com { namespace sun { namespace star { namespace beans {
+ struct Property;
+ struct PropertyValue;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace sdbc {
+ class XRow;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace ucb {
+ struct TransferInfo;
+} } } }
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+
+#define HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyRootFolderContent"
+#define HIERARCHY_FOLDER_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyFolderContent"
+#define HIERARCHY_LINK_CONTENT_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyLinkContent"
+
+//=========================================================================
+
+class HierarchyContentProperties
+{
+public:
+ HierarchyContentProperties() {};
+
+ HierarchyContentProperties( const HierarchyEntryData::Type & rType )
+ : m_aData( rType ),
+ m_aContentType( rType == HierarchyEntryData::FOLDER
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) ) {}
+
+ HierarchyContentProperties( const HierarchyEntryData & rData )
+ : m_aData( rData ),
+ m_aContentType( rData.getType() == HierarchyEntryData::FOLDER
+ ? rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE )
+ : rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) ) {}
+
+ const rtl::OUString & getName() const { return m_aData.getName(); }
+ void setName( const rtl::OUString & rName ) { m_aData.setName( rName ); };
+
+ const rtl::OUString & getTitle() const { return m_aData.getTitle(); }
+ void setTitle( const rtl::OUString & rTitle )
+ { m_aData.setTitle( rTitle ); };
+
+ const rtl::OUString & getTargetURL() const
+ { return m_aData.getTargetURL(); }
+ void setTargetURL( const rtl::OUString & rURL )
+ { m_aData.setTargetURL( rURL ); };
+
+ const rtl::OUString & getContentType() const { return m_aContentType; }
+
+ sal_Bool getIsFolder() const
+ { return m_aData.getType() == HierarchyEntryData::FOLDER; }
+
+ sal_Bool getIsDocument() const { return !getIsFolder(); }
+
+ com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
+ getCreatableContentsInfo() const;
+
+ const HierarchyEntryData & getHierarchyEntryData() const { return m_aData; }
+
+private:
+ HierarchyEntryData m_aData;
+ rtl::OUString m_aContentType;
+};
+
+//=========================================================================
+
+class HierarchyContentProvider;
+
+class HierarchyContent : public ::ucbhelper::ContentImplHelper,
+ public com::sun::star::ucb::XContentCreator
+{
+ enum ContentKind { LINK, FOLDER, ROOT };
+ enum ContentState { TRANSIENT, // created via CreateNewContent,
+ // but did not process "insert" yet
+ PERSISTENT, // processed "insert"
+ DEAD // processed "delete"
+ };
+
+ HierarchyContentProperties m_aProps;
+ ContentKind m_eKind;
+ ContentState m_eState;
+ HierarchyContentProvider* m_pProvider;
+ bool m_bCheckedReadOnly;
+ bool m_bIsReadOnly;
+
+private:
+ HierarchyContent(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const HierarchyContentProperties& rProps );
+ HierarchyContent(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* 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 sal_Bool hasData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+ sal_Bool hasData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier )
+ { return hasData( m_xSMgr, m_pProvider, Identifier ); }
+ static sal_Bool loadData(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ HierarchyContentProperties& rProps );
+ sal_Bool storeData();
+ sal_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 );
+ sal_Bool removeData();
+
+ void setKind( const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ bool isReadOnly();
+
+ sal_Bool isFolder() const { return ( m_eKind > LINK ); }
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::ucb::XContentIdentifier >
+ makeNewIdentifier( const rtl::OUString& rTitle );
+
+ typedef rtl::Reference< HierarchyContent > HierarchyContentRef;
+ typedef std::list< HierarchyContentRef > HierarchyContentRefList;
+ void queryChildren( HierarchyContentRefList& 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 );
+
+ void insert( 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 );
+
+public:
+ // Create existing content. Fail, if not already exists.
+ static HierarchyContent* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier );
+
+ // Create new content. Fail, if already exists.
+ static HierarchyContent* create(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ HierarchyContentProvider* pProvider,
+ const com::sun::star::uno::Reference<
+ com::sun::star::ucb::XContentIdentifier >& Identifier,
+ const com::sun::star::ucb::ContentInfo& Info );
+
+ virtual ~HierarchyContent();
+
+ // 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,
+ const HierarchyContentProperties& rData,
+ HierarchyContentProvider* pProvider,
+ const ::rtl::OUString& rContentId );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYCONTENT_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx b/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx
new file mode 100644
index 000000000000..a5371c213f1c
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchycontentcaps.cxx
@@ -0,0 +1,765 @@
+/*************************************************************************
+ *
+ * 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 folder folder link link
+ (new) (new)
+ ----------------------------------------------------------------
+ ContentType x x x x x
+ IsDocument x x x x x
+ IsFolder x x x x x
+ Title x x x x x
+ TargetURL x x
+ CreatableContentsInfo x x x x x
+
+ getCommandInfo x x x x x
+ getPropertySetInfo x x x x x
+ getPropertyValues x x x x x
+ setPropertyValues x x x x x
+ createNewContent x x
+ insert x x
+ delete x x
+ open x x
+ transfer x x
+
+ *************************************************************************/
+
+#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/ucb/CommandInfo.hpp>
+#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "hierarchycontent.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//
+// HierarchyContent 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
+// HierarchyContent::getPropertyValues(...) must be adapted too!
+//
+//=========================================================================
+
+// virtual
+uno::Sequence< beans::Property > HierarchyContent::getProperties(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_eKind == LINK )
+ {
+ //=================================================================
+ //
+ // Link: Supported properties
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static beans::Property aLinkPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( "TargetURL" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::READONLY
+ ),
+ 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( aLinkPropertyInfoTable );
+ }
+ else
+ {
+ static beans::Property aLinkPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( "TargetURL" ) ),
+ -1,
+ getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
+ beans::PropertyAttribute::BOUND
+ ),
+ 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( aLinkPropertyInfoTable );
+ }
+ }
+ else if ( m_eKind == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported properties
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( aFolderPropertyInfoTable );
+ }
+ else
+ {
+ static beans::Property aFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( aFolderPropertyInfoTable );
+ }
+ }
+ else
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported properties
+ //
+ //=================================================================
+
+ // Currently no difference between reonly /read-write
+ // -> all props ar read-only
+
+ static beans::Property aRootFolderPropertyInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////////
+ // Required 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( aRootFolderPropertyInfoTable );
+ }
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< ucb::CommandInfo > HierarchyContent::getCommands(
+ const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_eKind == LINK )
+ {
+ //=================================================================
+ //
+ // Link: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aLinkCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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
+ ///////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aLinkCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aLinkCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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()
+ )
+ ///////////////////////////////////////////////////////////
+ // New commands
+ ///////////////////////////////////////////////////////////
+ };
+ return MAKECMDSEQUENCE( aLinkCommandInfoTable );
+ }
+ }
+ else if ( m_eKind == FOLDER )
+ {
+ //=================================================================
+ //
+ // Folder: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( aFolderCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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
+ {
+ //=================================================================
+ //
+ // Root Folder: Supported commands
+ //
+ //=================================================================
+
+ if ( isReadOnly() )
+ {
+ static const ucb::CommandInfo aRootFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( aRootFolderCommandInfoTable );
+ }
+ else
+ {
+ static const ucb::CommandInfo aRootFolderCommandInfoTable[] =
+ {
+ ///////////////////////////////////////////////////////////
+ // Required 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( aRootFolderCommandInfoTable );
+ }
+ }
+}
diff --git a/ucb/source/ucp/hierarchy/hierarchydata.cxx b/ucb/source/ucp/hierarchy/hierarchydata.cxx
new file mode 100644
index 000000000000..d2e8f5031527
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydata.cxx
@@ -0,0 +1,1266 @@
+/*************************************************************************
+ *
+ * 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
+ **************************************************************************
+
+ - HierarchyEntry::move
+ --> Rewrite to use XNamed ( once this is supported by config db api ).
+
+ *************************************************************************/
+#include "hierarchydata.hxx"
+
+#include <vector>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#ifndef _COM_SUN_STAR_UTIL_XOFFICEINSTALLTIONDIRECTORIES_HPP_
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#endif
+#include "hierarchyprovider.hxx"
+#include "hierarchyuri.hxx"
+
+using namespace com::sun::star;
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+struct HierarchyEntry::iterator_Impl
+{
+ HierarchyEntryData entry;
+ uno::Reference< container::XHierarchicalNameAccess > dir;
+ uno::Reference< util::XOfficeInstallationDirectories > officeDirs;
+ uno::Sequence< rtl::OUString> names;
+ sal_Int32 pos;
+ iterator_Impl()
+ : officeDirs( 0 ), pos( -1 /* before first */ ) {};
+};
+
+//=========================================================================
+void makeXMLName( const rtl::OUString & rIn, rtl::OUStringBuffer & rBuffer )
+{
+ sal_Int32 nCount = rIn.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const sal_Unicode c = rIn.getStr()[ n ];
+ switch ( c )
+ {
+ case '&':
+ rBuffer.appendAscii( "&amp;" );
+ break;
+
+ case '"':
+ rBuffer.appendAscii( "&quot;" );
+ break;
+
+ case '\'':
+ rBuffer.appendAscii( "&apos;" );
+ break;
+
+ case '<':
+ rBuffer.appendAscii( "&lt;" );
+ break;
+
+ case '>':
+ rBuffer.appendAscii( "&gt;" );
+ break;
+
+ default:
+ rBuffer.append( c );
+ break;
+ }
+ }
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyEntry Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+#define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
+#define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+
+// describe path of cfg entry
+#define CFGPROPERTY_NODEPATH "nodepath"
+
+//=========================================================================
+HierarchyEntry::HierarchyEntry(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
+ HierarchyContentProvider* pProvider,
+ const rtl::OUString& rURL )
+: m_xSMgr( rSMgr ),
+ m_xOfficeInstDirs( pProvider->getOfficeInstallationDirectories() ),
+ m_bTriedToGetRootReadAccess( sal_False )
+{
+ HierarchyUri aUri( rURL );
+ m_aServiceSpecifier = aUri.getService();
+
+ if ( pProvider )
+ {
+ m_xConfigProvider
+ = pProvider->getConfigProvider( m_aServiceSpecifier );
+ m_xRootReadAccess
+ = pProvider->getRootConfigReadNameAccess( m_aServiceSpecifier );
+ }
+
+ // Note: do not init m_aPath in init list. createPathFromHierarchyURL
+ // needs m_xSMgr and m_aMutex.
+ m_aPath = createPathFromHierarchyURL( aUri );
+
+ // Extract language independent name from URL.
+ sal_Int32 nPos = rURL.lastIndexOf( '/' );
+ if ( nPos > HIERARCHY_URL_SCHEME_LENGTH )
+ m_aName = rURL.copy( nPos + 1 );
+ else
+ OSL_ENSURE( sal_False, "HierarchyEntry - Invalid URL!" );
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::hasData()
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
+ = getRootReadAccess();
+
+ OSL_ENSURE( xRootReadAccess.is(), "HierarchyEntry::hasData - No root!" );
+
+ if ( xRootReadAccess.is() )
+ return xRootReadAccess->hasByHierarchicalName( m_aPath );
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::getData( HierarchyEntryData& rData )
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ uno::Reference< container::XHierarchicalNameAccess > xRootReadAccess
+ = getRootReadAccess();
+
+ OSL_ENSURE( xRootReadAccess.is(),
+ "HierarchyEntry::getData - No root!" );
+
+ if ( xRootReadAccess.is() )
+ {
+ rtl::OUString aTitlePath = m_aPath;
+ aTitlePath += rtl::OUString::createFromAscii( "/Title" );
+
+ // Note: Avoid NoSuchElementExceptions, because exceptions are
+ // relatively 'expensive'. Checking for availability of
+ // title value is sufficient here, because if it is
+ // there, the other values will be available too.
+ if ( !xRootReadAccess->hasByHierarchicalName( aTitlePath ) )
+ return sal_False;
+
+ rtl::OUString aValue;
+
+ // Get Title value.
+ if ( !( xRootReadAccess->getByHierarchicalName( aTitlePath )
+ >>= aValue ) )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Got no Title value!" );
+ return sal_False;
+ }
+
+ rData.setTitle( aValue );
+
+ // Get TargetURL value.
+ rtl::OUString aTargetURLPath = m_aPath;
+ aTargetURLPath += rtl::OUString::createFromAscii( "/TargetURL" );
+ if ( !( xRootReadAccess->getByHierarchicalName( aTargetURLPath )
+ >>= aValue ) )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Got no TargetURL value!" );
+ return sal_False;
+ }
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion directory must
+ // never be stored directly. A placeholder is used instead. Replace
+ // it by actual installation directory.
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_xOfficeInstDirs->makeAbsoluteURL( aValue );
+ rData.setTargetURL( aValue );
+
+ rtl::OUString aTypePath = m_aPath;
+ aTypePath += rtl::OUString::createFromAscii( "/Type" );
+ if ( xRootReadAccess->hasByHierarchicalName( aTypePath ) )
+ {
+ // Might not be present since it was introduced long after
+ // Title and TargetURL (#82433#)... So not getting it is
+ // not an error.
+
+ // Get Type value.
+ sal_Int32 nType = 0;
+ if ( xRootReadAccess->getByHierarchicalName( aTypePath )
+ >>= nType )
+ {
+ if ( nType == 0 )
+ {
+ rData.setType( HierarchyEntryData::LINK );
+ }
+ else if ( nType == 1 )
+ {
+ rData.setType( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Unknown Type value!" );
+ return sal_False;
+ }
+ }
+ }
+
+ rData.setName( m_aName );
+ return sal_True;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - caught NoSuchElementException!" );
+ }
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::setData(
+ const HierarchyEntryData& rData, sal_Bool bCreate )
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create parent's key. It must exist!
+
+ rtl::OUString aParentPath;
+ sal_Bool bRoot = sal_True;
+
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1,
+ "HierarchyEntry::setData - Wrong path!" );
+
+ aParentPath += m_aPath.copy( 0, nPos );
+ bRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< util::XChangesBatch > xBatch(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "HierarchyEntry::setData - No batch!" );
+
+ uno::Reference< container::XNameAccess > xParentNameAccess(
+ xBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNameAccess.is(),
+ "HierarchyEntry::setData - No name access!" );
+
+ if ( xBatch.is() && xParentNameAccess.is() )
+ {
+ // Try to create own key. It must not exist!
+
+ sal_Bool bExists = sal_True;
+ uno::Any aMyKey;
+
+ try
+ {
+ uno::Reference< container::XNameAccess > xNameAccess;
+
+ if ( bRoot )
+ {
+ xNameAccess = xParentNameAccess;
+ }
+ else
+ {
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xNameAccess;
+ }
+
+ if ( xNameAccess->hasByName( m_aName ) )
+ aMyKey = xNameAccess->getByName( m_aName );
+ else
+ bExists = sal_False;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ bExists = sal_False;
+ }
+
+ uno::Reference< container::XNameReplace > xNameReplace;
+ uno::Reference< container::XNameContainer > xContainer;
+
+ if ( bExists )
+ {
+ // Key exists. Replace values.
+
+ aMyKey >>= xNameReplace;
+
+ OSL_ENSURE( xNameReplace.is(),
+ "HierarchyEntry::setData - No name replace!" );
+ }
+ else
+ {
+ if ( !bCreate )
+ return sal_True;
+
+ // Key does not exist. Create / fill / insert it.
+
+ uno::Reference< lang::XSingleServiceFactory > xFac;
+
+ if ( bRoot )
+ {
+ // Special handling for children of root,
+ // which is not an entry. It's only a set
+ // of entries.
+ xFac = uno::Reference< lang::XSingleServiceFactory >(
+ xParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ // Append new entry to parents child list,
+ // which is a set of entries.
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii(
+ "Children" ) ) >>= xFac;
+ }
+
+ OSL_ENSURE( xFac.is(),
+ "HierarchyEntry::setData - No factory!" );
+
+ if ( xFac.is() )
+ {
+ xNameReplace
+ = uno::Reference< container::XNameReplace >(
+ xFac->createInstance(), uno::UNO_QUERY );
+
+ OSL_ENSURE( xNameReplace.is(),
+ "HierarchyEntry::setData - No name replace!" );
+
+ if ( xNameReplace.is() )
+ {
+ xContainer
+ = uno::Reference< container::XNameContainer >(
+ xFac, uno::UNO_QUERY );
+
+ OSL_ENSURE( xContainer.is(),
+ "HierarchyEntry::setData - No container!" );
+ }
+ }
+ }
+
+ if ( xNameReplace.is() )
+ {
+ // Set Title value.
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Title" ),
+ uno::makeAny( rData.getTitle() ) );
+
+ // Set TargetURL value.
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion
+ // directory must never be stored directly. Use a
+ // placeholder instead.
+ rtl::OUString aValue( rData.getTargetURL() );
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue
+ = m_xOfficeInstDirs->makeRelocatableURL( aValue );
+
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ uno::makeAny( aValue ) );
+
+ // Set Type value.
+ sal_Int32 nType
+ = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
+ xNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Type" ),
+ uno::makeAny( nType ) );
+
+ if ( xContainer.is() )
+ xContainer->insertByName(
+ m_aName, uno::makeAny( xNameReplace ) );
+
+ // Commit changes.
+ xBatch->commitChanges();
+ return sal_True;
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // replaceByName, insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught IllegalArgumentException!" );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // replaceByName, getByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught NoSuchElementException!" );
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught ElementExistException!" );
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // replaceByName, insertByName, getByName, commitChanges
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught WrappedTargetException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::setData - caught Exception!" );
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::move(
+ const rtl::OUString& rNewURL, const HierarchyEntryData& rData )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ rtl::OUString aNewPath = createPathFromHierarchyURL( rNewURL );
+
+ if ( aNewPath == m_aPath )
+ return sal_True;
+
+#if 0
+ // In the "near future"... ( not yet implemented in config db )
+
+ - get update access for m_aPath
+ - update access -> XNamed
+ - xNamed::setName( newName )
+ - updateaccess commit
+#else
+
+ sal_Bool bOldRoot = sal_True;
+ uno::Reference< util::XChangesBatch > xOldParentBatch;
+
+ rtl::OUString aNewKey;
+ sal_Int32 nURLPos = rNewURL.lastIndexOf( '/' );
+ if ( nURLPos > HIERARCHY_URL_SCHEME_LENGTH )
+ aNewKey = rNewURL.copy( nURLPos + 1 );
+ else
+ {
+ OSL_ENSURE( sal_False, "HierarchyEntry::move - Invalid URL!" );
+ return sal_False;
+ }
+
+ sal_Bool bNewRoot = sal_True;
+ uno::Reference< util::XChangesBatch > xNewParentBatch;
+
+ sal_Bool bDifferentParents = sal_True;
+
+ try
+ {
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( !m_xConfigProvider.is() )
+ return sal_False;
+
+ rtl::OUString aOldParentPath;
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
+
+ aOldParentPath += m_aPath.copy( 0, nPos );
+ bOldRoot = sal_False;
+ }
+
+ rtl::OUString aNewParentPath;
+ nPos = aNewPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = aNewPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1, "HierarchyEntry::move - Wrong path!" );
+
+ aNewParentPath += aNewPath.copy( 0, nPos );
+ bNewRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aOldParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ xOldParentBatch = uno::Reference< util::XChangesBatch >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xOldParentBatch.is(), "HierarchyEntry::move - No batch!" );
+
+ if ( !xOldParentBatch.is() )
+ return sal_False;
+
+ if ( aOldParentPath == aNewParentPath )
+ {
+ bDifferentParents = sal_False;
+ xNewParentBatch = xOldParentBatch;
+ }
+ else
+ {
+ bDifferentParents = sal_True;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aNewParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ xNewParentBatch = uno::Reference< util::XChangesBatch >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE(
+ xNewParentBatch.is(), "HierarchyEntry::move - No batch!" );
+
+ if ( !xNewParentBatch.is() )
+ return sal_False;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False, "HierarchyEntry::move - caught Exception!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (1) Get entry...
+ //////////////////////////////////////////////////////////////////////
+
+ uno::Any aEntry;
+ uno::Reference< container::XNameAccess > xOldParentNameAccess;
+ uno::Reference< container::XNameContainer > xOldNameContainer;
+
+ try
+ {
+ xOldParentNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xOldParentBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xOldParentNameAccess.is(),
+ "HierarchyEntry::move - No name access!" );
+
+ if ( !xOldParentNameAccess.is() )
+ return sal_False;
+
+ if ( bOldRoot )
+ {
+ xOldNameContainer = uno::Reference< container::XNameContainer >(
+ xOldParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ xOldParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xOldNameContainer;
+ }
+
+ aEntry = xOldNameContainer->getByName( m_aName );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (2) Remove entry... Note: Insert BEFORE remove does not work!
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ xOldNameContainer->removeByName( m_aName );
+ xOldParentBatch->commitChanges();
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName, removeByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // (3) Insert entry at new parent...
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ uno::Reference< container::XNameReplace > xNewNameReplace;
+ aEntry >>= xNewNameReplace;
+
+ OSL_ENSURE( xNewNameReplace.is(),
+ "HierarchyEntry::move - No name replace!" );
+
+ if ( !xNewNameReplace.is() )
+ return sal_False;
+
+ uno::Reference< container::XNameAccess > xNewParentNameAccess;
+ if ( bDifferentParents )
+ xNewParentNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xNewParentBatch, uno::UNO_QUERY );
+ else
+ xNewParentNameAccess = xOldParentNameAccess;
+
+ OSL_ENSURE( xNewParentNameAccess.is(),
+ "HierarchyEntry::move - No name access!" );
+
+ if ( !xNewParentNameAccess.is() )
+ return sal_False;
+
+ uno::Reference< container::XNameContainer > xNewNameContainer;
+ if ( bDifferentParents )
+ {
+ if ( bNewRoot )
+ {
+ xNewNameContainer
+ = uno::Reference< container::XNameContainer >(
+ xNewParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ xNewParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xNewNameContainer;
+ }
+ }
+ else
+ xNewNameContainer = xOldNameContainer;
+
+ if ( !xNewNameContainer.is() )
+ return sal_False;
+
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Title" ),
+ uno::makeAny( rData.getTitle() ) );
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion
+ // directory must never be stored directly. Use a placeholder
+ // instead.
+ rtl::OUString aValue( rData.getTargetURL() );
+ if ( m_xOfficeInstDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_xOfficeInstDirs->makeRelocatableURL( aValue );
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "TargetURL" ),
+ uno::makeAny( aValue ) );
+ sal_Int32 nType = rData.getType() == HierarchyEntryData::LINK ? 0 : 1;
+ xNewNameReplace->replaceByName(
+ rtl::OUString::createFromAscii( "Type" ),
+ uno::makeAny( nType ) );
+
+ xNewNameContainer->insertByName( aNewKey, aEntry );
+ xNewParentBatch->commitChanges();
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // replaceByName, insertByName, getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught NoSuchElementException!" );
+ return sal_False;
+ }
+ catch ( lang::IllegalArgumentException const & )
+ {
+ // replaceByName, insertByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::move - caught IllegalArgumentException!" );
+ return sal_False;
+ }
+ catch ( container::ElementExistException const & )
+ {
+ // insertByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught ElementExistException!" );
+ return sal_False;
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // replaceByName, insertByName, getByName
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+
+#if 0
+ //////////////////////////////////////////////////////////////////////
+ // (4) Commit changes...
+ //////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ xNewParentBatch->commitChanges();
+
+ if ( bDifferentParents )
+ xOldParentBatch->commitChanges();
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // commitChanges
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::move - caught WrappedTargetException!" );
+ return sal_False;
+ }
+#endif
+
+ return sal_True;
+#endif
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::remove()
+{
+ try
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create parent's key. It must exist!
+
+ rtl::OUString aParentPath;
+ sal_Bool bRoot = sal_True;
+
+ sal_Int32 nPos = m_aPath.lastIndexOf( '/' );
+ if ( nPos != -1 )
+ {
+ // Skip "/Children" segment of the path, too.
+ nPos = m_aPath.lastIndexOf( '/', nPos - 1 );
+
+ OSL_ENSURE( nPos != -1,
+ "HierarchyEntry::remove - Wrong path!" );
+
+ aParentPath += m_aPath.copy( 0, nPos );
+ bRoot = sal_False;
+ }
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+
+ aProperty.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= aParentPath;
+ aArguments[ 0 ] <<= aProperty;
+
+ uno::Reference< util::XChangesBatch > xBatch(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ READWRITE_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( xBatch.is(),
+ "HierarchyEntry::remove - No batch!" );
+
+ uno::Reference< container::XNameAccess > xParentNameAccess(
+ xBatch, uno::UNO_QUERY );
+
+ OSL_ENSURE( xParentNameAccess.is(),
+ "HierarchyEntry::remove - No name access!" );
+
+ if ( xBatch.is() && xParentNameAccess.is() )
+ {
+ uno::Reference< container::XNameContainer > xContainer;
+
+ if ( bRoot )
+ {
+ // Special handling for children of root,
+ // which is not an entry. It's only a set
+ // of entries.
+ xContainer = uno::Reference< container::XNameContainer >(
+ xParentNameAccess, uno::UNO_QUERY );
+ }
+ else
+ {
+ // Append new entry to parents child list,
+ // which is a set of entries.
+ xParentNameAccess->getByName(
+ rtl::OUString::createFromAscii( "Children" ) )
+ >>= xContainer;
+ }
+
+ OSL_ENSURE( xContainer.is(),
+ "HierarchyEntry::remove - No container!" );
+
+ if ( xContainer.is() )
+ {
+ xContainer->removeByName( m_aName );
+ xBatch->commitChanges();
+ return sal_True;
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ // getByName, removeByName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::remove - caught NoSuchElementException!" );
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ // getByName, commitChanges
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::remove - caught WrappedTargetException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::remove - caught Exception!" );
+ }
+
+ return sal_False;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::first( iterator& it )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( it.m_pImpl->pos == -1 )
+ {
+ // Init...
+
+ try
+ {
+ uno::Reference< container::XHierarchicalNameAccess >
+ xRootHierNameAccess = getRootReadAccess();
+
+ if ( xRootHierNameAccess.is() )
+ {
+ uno::Reference< container::XNameAccess > xNameAccess;
+
+ if ( m_aPath.getLength() > 0 )
+ {
+ rtl::OUString aPath = m_aPath;
+ aPath += rtl::OUString::createFromAscii( "/Children" );
+
+ xRootHierNameAccess->getByHierarchicalName( aPath )
+ >>= xNameAccess;
+ }
+ else
+ xNameAccess
+ = uno::Reference< container::XNameAccess >(
+ xRootHierNameAccess, uno::UNO_QUERY );
+
+ OSL_ENSURE( xNameAccess.is(),
+ "HierarchyEntry::first - No name access!" );
+
+ if ( xNameAccess.is() )
+ it.m_pImpl->names = xNameAccess->getElementNames();
+
+ uno::Reference< container::XHierarchicalNameAccess >
+ xHierNameAccess( xNameAccess, uno::UNO_QUERY );
+
+ OSL_ENSURE( xHierNameAccess.is(),
+ "HierarchyEntry::first - No hier. name access!" );
+
+ it.m_pImpl->dir = xHierNameAccess;
+
+ it.m_pImpl->officeDirs = m_xOfficeInstDirs;
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( container::NoSuchElementException const& )
+ {
+ // getByHierarchicalName
+
+ OSL_ENSURE(
+ sal_False,
+ "HierarchyEntry::first - caught NoSuchElementException!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::first - caught Exception!" );
+ }
+ }
+
+ if ( it.m_pImpl->names.getLength() == 0 )
+ return sal_False;
+
+ it.m_pImpl->pos = 0;
+ return sal_True;
+}
+
+//=========================================================================
+sal_Bool HierarchyEntry::next( iterator& it )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( it.m_pImpl->pos == -1 )
+ return first( it );
+
+ ++(it.m_pImpl->pos);
+
+ return ( it.m_pImpl->pos < it.m_pImpl->names.getLength() );
+}
+
+//=========================================================================
+rtl::OUString HierarchyEntry::createPathFromHierarchyURL(
+ const HierarchyUri& rURI )
+{
+ // Transform path....
+ // folder/subfolder/subsubfolder
+ // --> ['folder']/Children/['subfolder']/Children/['subsubfolder']
+
+ const rtl::OUString aPath = rURI.getPath().copy( 1 ); // skip leading slash.
+ sal_Int32 nLen = aPath.getLength();
+
+ if ( nLen )
+ {
+ rtl::OUStringBuffer aNewPath;
+ aNewPath.appendAscii( "['" );
+
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = aPath.indexOf( '/' );
+
+ do
+ {
+ if ( nEnd == -1 )
+ nEnd = nLen;
+
+ rtl::OUString aToken = aPath.copy( nStart, nEnd - nStart );
+ makeXMLName( aToken, aNewPath );
+
+ if ( nEnd != nLen )
+ {
+ aNewPath.appendAscii( "']/Children/['" );
+ nStart = nEnd + 1;
+ nEnd = aPath.indexOf( '/', nStart );
+ }
+ else
+ aNewPath.appendAscii( "']" );
+ }
+ while ( nEnd != nLen );
+
+ return aNewPath.makeStringAndClear();
+ }
+
+ return aPath;
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess >
+HierarchyEntry::getRootReadAccess()
+{
+ if ( !m_xRootReadAccess.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_xRootReadAccess.is() )
+ {
+ if ( m_bTriedToGetRootReadAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getRootReadAccess - "
+ "Unable to read any config data! -> #82494#" );
+ return uno::Reference< container::XHierarchicalNameAccess >();
+ }
+
+ try
+ {
+ if ( !m_xConfigProvider.is() )
+ m_xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( m_aServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( m_xConfigProvider.is() )
+ {
+ // Create Root object.
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
+ aProperty.Value <<= rtl::OUString(); // root path
+ aArguments[ 0 ] <<= aProperty;
+
+ m_bTriedToGetRootReadAccess = sal_True;
+
+ m_xRootReadAccess
+ = uno::Reference< container::XHierarchicalNameAccess >(
+ m_xConfigProvider->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ READ_SERVICE_NAME ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getRootReadAccess - "
+ "caught Exception!" );
+ }
+ }
+ }
+ return m_xRootReadAccess;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyEntry::iterator Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyEntry::iterator::iterator()
+{
+ m_pImpl = new iterator_Impl;
+}
+
+//=========================================================================
+HierarchyEntry::iterator::~iterator()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+const HierarchyEntryData& HierarchyEntry::iterator::operator*() const
+{
+ if ( ( m_pImpl->pos != -1 )
+ && ( m_pImpl->dir.is() )
+ && ( m_pImpl->pos < m_pImpl->names.getLength() ) )
+ {
+ try
+ {
+ rtl::OUStringBuffer aKey;
+ aKey.appendAscii( "['" );
+ makeXMLName( m_pImpl->names.getConstArray()[ m_pImpl->pos ], aKey );
+ aKey.appendAscii( "']" );
+
+ rtl::OUString aTitle = aKey.makeStringAndClear();
+ rtl::OUString aTargetURL = aTitle;
+ rtl::OUString aType = aTitle;
+
+ aTitle += rtl::OUString::createFromAscii( "/Title" );
+ aTargetURL += rtl::OUString::createFromAscii( "/TargetURL" );
+ aType += rtl::OUString::createFromAscii( "/Type" );
+
+ rtl::OUString aValue;
+ m_pImpl->dir->getByHierarchicalName( aTitle ) >>= aValue;
+ m_pImpl->entry.setTitle( aValue );
+
+ m_pImpl->dir->getByHierarchicalName( aTargetURL ) >>= aValue;
+
+ // TargetURL property may contain a reference to the Office
+ // installation directory. To ensure a reloctable office
+ // installation, the path to the office installtion directory must
+ // never be stored directly. A placeholder is used instead. Replace
+ // it by actual installation directory.
+ if ( m_pImpl->officeDirs.is() && ( aValue.getLength() > 0 ) )
+ aValue = m_pImpl->officeDirs->makeAbsoluteURL( aValue );
+ m_pImpl->entry.setTargetURL( aValue );
+
+ if ( m_pImpl->dir->hasByHierarchicalName( aType ) )
+ {
+ // Might not be present since it was introduced long
+ // after Title and TargetURL (#82433#)... So not getting
+ // it is not an error.
+
+ // Get Type value.
+ sal_Int32 nType = 0;
+ if ( m_pImpl->dir->getByHierarchicalName( aType ) >>= nType )
+ {
+ if ( nType == 0 )
+ {
+ m_pImpl->entry.setType( HierarchyEntryData::LINK );
+ }
+ else if ( nType == 1 )
+ {
+ m_pImpl->entry.setType( HierarchyEntryData::FOLDER );
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyEntry::getData - "
+ "Unknown Type value!" );
+ }
+ }
+ }
+
+ m_pImpl->entry.setName(
+ m_pImpl->names.getConstArray()[ m_pImpl->pos ] );
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ m_pImpl->entry = HierarchyEntryData();
+ }
+ }
+
+ return m_pImpl->entry;
+}
+
+} // namespace hierarchy_ucp
diff --git a/ucb/source/ucp/hierarchy/hierarchydata.hxx b/ucb/source/ucp/hierarchy/hierarchydata.hxx
new file mode 100644
index 000000000000..769611342baf
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydata.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYDATA_HXX
+#define _HIERARCHYDATA_HXX
+
+#include <rtl/ustring.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace util {
+ class XOfficeInstallationDirectories;
+ }
+} } }
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+
+class HierarchyEntryData
+{
+public:
+ enum Type { NONE, LINK, FOLDER };
+
+ HierarchyEntryData() : m_aType( NONE ) {}
+ HierarchyEntryData( const Type & rType ) : m_aType( rType ) {}
+
+ const rtl::OUString & getName() const { return m_aName; }
+ void setName( const rtl::OUString & rName ) { m_aName = rName; }
+
+ const rtl::OUString & getTitle() const { return m_aTitle; }
+ void setTitle( const rtl::OUString & rTitle ) { m_aTitle = rTitle; }
+
+ const rtl::OUString & getTargetURL() const { return m_aTargetURL; }
+ void setTargetURL( const rtl::OUString & rURL ) { m_aTargetURL = rURL; }
+
+ Type getType() const
+ { return ( m_aType != NONE ) ? m_aType
+ : m_aTargetURL.getLength()
+ ? LINK
+ : FOLDER; }
+ void setType( const Type & rType ) { m_aType = rType; }
+
+private:
+ rtl::OUString m_aName; // Name (language independent)
+ rtl::OUString m_aTitle; // Title (language dependent)
+ rtl::OUString m_aTargetURL; // Target URL ( links only )
+ Type m_aType; // Type
+};
+
+//=========================================================================
+
+class HierarchyContentProvider;
+class HierarchyUri;
+
+class HierarchyEntry
+{
+ ::rtl::OUString m_aServiceSpecifier;
+ ::rtl::OUString m_aName;
+ ::rtl::OUString m_aPath;
+ ::osl::Mutex m_aMutex;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess >
+ m_xRootReadAccess;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::util::XOfficeInstallationDirectories >
+ m_xOfficeInstDirs;
+ sal_Bool m_bTriedToGetRootReadAccess; // #82494#
+
+private:
+ ::rtl::OUString createPathFromHierarchyURL( const HierarchyUri & rURI );
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess >
+ getRootReadAccess();
+
+public:
+ HierarchyEntry( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
+ HierarchyContentProvider* pProvider,
+ const ::rtl::OUString& rURL );
+
+ sal_Bool hasData();
+
+ sal_Bool getData( HierarchyEntryData& rData );
+
+ sal_Bool setData( const HierarchyEntryData& rData, sal_Bool bCreate );
+
+ sal_Bool move( const ::rtl::OUString& rNewURL,
+ const HierarchyEntryData& rData );
+
+ sal_Bool remove();
+
+ // Iteration.
+
+ struct iterator_Impl;
+
+ class iterator
+ {
+ friend class HierarchyEntry;
+
+ iterator_Impl* m_pImpl;
+
+ public:
+ iterator();
+ ~iterator();
+
+ const HierarchyEntryData& operator*() const;
+ };
+
+ sal_Bool first( iterator& it );
+ sal_Bool next ( iterator& it );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYDATA_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasource.cxx b/ucb/source/ucp/hierarchy/hierarchydatasource.cxx
new file mode 100644
index 000000000000..467259caf0eb
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasource.cxx
@@ -0,0 +1,1116 @@
+/*************************************************************************
+ *
+ * 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
+ **************************************************************************
+
+ Note: Configuration Management classes do not support XAggregation.
+ So I have to wrap the interesting interfaces manually.
+
+ *************************************************************************/
+#include "hierarchydatasource.hxx"
+#include <osl/diagnose.h>
+
+#include "osl/doublecheckedlocking.h"
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+
+// describe path of cfg entry
+#define CFGPROPERTY_NODEPATH "nodepath"
+// true->async. update; false->sync. update
+#define CFGPROPERTY_LAZYWRITE "lazywrite"
+
+#define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
+#define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
+
+#define CONFIG_PROVIDER_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationProvider"
+#define CONFIG_READ_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationAccess"
+#define CONFIG_READWRITE_SERVICE_NAME \
+ "com.sun.star.configuration.ConfigurationUpdateAccess"
+#define CONFIG_DATA_ROOT_KEY \
+ "/org.openoffice.ucb.Hierarchy/Root"
+
+//=========================================================================
+
+namespace hcp_impl
+{
+
+//=========================================================================
+//
+// HierarchyDataReadAccess Implementation.
+//
+//=========================================================================
+
+class HierarchyDataAccess : public cppu::OWeakObject,
+ public lang::XServiceInfo,
+ public lang::XTypeProvider,
+ public lang::XComponent,
+ public lang::XSingleServiceFactory,
+ public container::XHierarchicalNameAccess,
+ public container::XNameContainer,
+ public util::XChangesNotifier,
+ public util::XChangesBatch
+{
+ osl::Mutex m_aMutex;
+ uno::Reference< uno::XInterface > m_xConfigAccess;
+ uno::Reference< lang::XComponent > m_xCfgC;
+ uno::Reference< lang::XSingleServiceFactory > m_xCfgSSF;
+ uno::Reference< container::XHierarchicalNameAccess > m_xCfgHNA;
+ uno::Reference< container::XNameContainer > m_xCfgNC;
+ uno::Reference< container::XNameReplace > m_xCfgNR;
+ uno::Reference< container::XNameAccess > m_xCfgNA;
+ uno::Reference< container::XElementAccess > m_xCfgEA;
+ uno::Reference< util::XChangesNotifier > m_xCfgCN;
+ uno::Reference< util::XChangesBatch > m_xCfgCB;
+ bool m_bReadOnly;
+
+public:
+ HierarchyDataAccess( const uno::Reference<
+ uno::XInterface > & xConfigAccess,
+ bool bReadOnly );
+ virtual ~HierarchyDataAccess();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose()
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ addEventListener( const uno::Reference< lang::XEventListener > & xListener )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ removeEventListener( const uno::Reference<
+ lang::XEventListener > & aListener )
+ throw ( uno::RuntimeException );
+
+ // XSingleServiceFactory
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstance()
+ throw ( uno::Exception, uno::RuntimeException );
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const uno::Sequence< uno::Any > & aArguments )
+ throw ( uno::Exception, uno::RuntimeException );
+
+ // XHierarchicalNameAccess
+ virtual uno::Any SAL_CALL
+ getByHierarchicalName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException, uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByHierarchicalName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException );
+
+ // XNameContainer
+ virtual void SAL_CALL
+ insertByName( const rtl::OUString & aName, const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::ElementExistException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+ virtual void SAL_CALL
+ removeByName( const rtl::OUString & Name )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+
+ // XNameReplace ( base of XNameContainer )
+ virtual void SAL_CALL
+ replaceByName( const rtl::OUString & aName, const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+
+ // XNameAccess ( base of XNameReplace )
+ virtual uno::Any SAL_CALL
+ getByName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException );
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames()
+ throw ( uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException );
+
+ // XElementAccess ( base of XNameAccess )
+ virtual uno::Type SAL_CALL
+ getElementType()
+ throw ( uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasElements()
+ throw ( uno::RuntimeException );
+
+ // XChangesNotifier
+ virtual void SAL_CALL
+ addChangesListener( const uno::Reference<
+ util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL
+ removeChangesListener( const uno::Reference<
+ util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException );
+
+ // XChangesBatch
+ virtual void SAL_CALL
+ commitChanges()
+ throw ( lang::WrappedTargetException, uno::RuntimeException );
+ virtual sal_Bool SAL_CALL
+ hasPendingChanges()
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< util::ElementChange > SAL_CALL
+ getPendingChanges()
+ throw ( uno::RuntimeException );
+};
+
+} // namespace hcp_impl
+
+using namespace hcp_impl;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyDataSource Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyDataSource::HierarchyDataSource(
+ const uno::Reference< lang::XMultiServiceFactory > & rxServiceMgr )
+: m_xSMgr( rxServiceMgr ),
+ m_pDisposeEventListeners( 0 )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyDataSource::~HierarchyDataSource()
+{
+ delete m_pDisposeEventListeners;
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( HierarchyDataSource,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ lang::XComponent,
+ lang::XMultiServiceFactory );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( HierarchyDataSource,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ lang::XComponent,
+ lang::XMultiServiceFactory );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_0( HierarchyDataSource,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyDataSource" ) )
+{
+ uno::Sequence< rtl::OUString > aSNS( 2 );
+ aSNS[ 0 ] = rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.DefaultHierarchyDataSource" );
+ aSNS[ 1 ] = rtl::OUString::createFromAscii(
+ "com.sun.star.ucb.HierarchyDataSource" );
+ return aSNS;
+}
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyDataSource );
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataSource::dispose()
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
+ {
+ lang::EventObject aEvt;
+ aEvt.Source = static_cast< lang::XComponent * >( this );
+ m_pDisposeEventListeners->disposeAndClear( aEvt );
+ }
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataSource::addEventListener(
+ const uno::Reference< lang::XEventListener > & Listener )
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( !m_pDisposeEventListeners )
+ m_pDisposeEventListeners
+ = new cppu::OInterfaceContainerHelper( m_aMutex );
+
+ m_pDisposeEventListeners->addInterface( Listener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataSource::removeEventListener(
+ const uno::Reference< lang::XEventListener > & Listener )
+ throw( uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ if ( m_pDisposeEventListeners )
+ m_pDisposeEventListeners->removeInterface( Listener );
+}
+
+//=========================================================================
+//
+// XMultiServiceFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstance( const rtl::OUString & aServiceSpecifier )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ // Create view to root node.
+
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
+ aProp.Value <<=
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
+
+ uno::Sequence< uno::Any > aArguments( 1 );
+ aArguments[ 0 ] <<= aProp;
+
+ return createInstanceWithArguments( aServiceSpecifier, aArguments, false );
+}
+
+//=========================================================================
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstanceWithArguments(
+ const rtl::OUString & ServiceSpecifier,
+ const uno::Sequence< uno::Any > & Arguments )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ return createInstanceWithArguments( ServiceSpecifier, Arguments, true );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL
+HierarchyDataSource::getAvailableServiceNames()
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< rtl::OUString > aNames( 2 );
+ aNames[ 0 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
+ aNames[ 1 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
+ return aNames;
+}
+
+//=========================================================================
+//
+// Non-interface methods
+//
+//=========================================================================
+
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataSource::createInstanceWithArguments(
+ const rtl::OUString & ServiceSpecifier,
+ const uno::Sequence< uno::Any > & Arguments,
+ bool bCheckArgs )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+
+ // Check service specifier.
+ bool bReadOnly = !!ServiceSpecifier.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( READ_SERVICE_NAME ) );
+ bool bReadWrite = !bReadOnly &&
+ ServiceSpecifier.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( READWRITE_SERVICE_NAME ) );
+
+ if ( !bReadOnly && !bReadWrite )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Unsupported service specifier!" );
+ return uno::Reference< uno::XInterface >();
+ }
+
+ uno::Sequence< uno::Any > aNewArgs( Arguments );
+
+ bool bHasLazyWriteProp = bReadOnly; // property must be added only if
+ // a writable view is requested.
+ if ( bCheckArgs )
+ {
+ // Check arguments.
+ bool bHasNodePath = false;
+ sal_Int32 nCount = Arguments.getLength();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ beans::PropertyValue aProp;
+ if ( Arguments[ n ] >>= aProp )
+ {
+ if ( aProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( CFGPROPERTY_NODEPATH ) ) )
+ {
+ rtl::OUString aPath;
+ if ( aProp.Value >>= aPath )
+ {
+ bHasNodePath = true;
+
+ // Create path to data inside the configuration.
+ rtl::OUString aConfigPath;
+ if ( !createConfigPath( aPath, aConfigPath ) )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::"
+ "createInstanceWithArguments - "
+ "Invalid node path!" );
+ return uno::Reference< uno::XInterface >();
+ }
+
+ aProp.Value <<= aConfigPath;
+
+ // Set new path in arguments.
+ aNewArgs[ n ] <<= aProp;
+
+ if ( bHasLazyWriteProp )
+ break;
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Invalid type for property 'nodepath'!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+ else if ( aProp.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ CFGPROPERTY_LAZYWRITE ) ) )
+ {
+ if ( aProp.Value.getValueType() == getCppuBooleanType() )
+ {
+ bHasLazyWriteProp = true;
+
+ if ( bHasNodePath )
+ break;
+ }
+ else
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Invalid type for property 'lazywrite'!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+ }
+ }
+
+ if ( !bHasNodePath )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "No 'nodepath' property!" );
+ return uno::Reference< uno::XInterface >();
+ }
+ }
+
+ // Create Configuration Provider.
+ uno::Reference< lang::XMultiServiceFactory > xProv = getConfigProvider();
+ if ( !xProv.is() )
+ return uno::Reference< uno::XInterface >();
+
+ uno::Reference< uno::XInterface > xConfigAccess;
+ try
+ {
+ if ( bReadOnly )
+ {
+ // Create configuration read-only access object.
+ xConfigAccess = xProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_READ_SERVICE_NAME ) ),
+ aNewArgs );
+ }
+ else
+ {
+ // Append 'lazywrite' property value, if not already present.
+ if ( !bHasLazyWriteProp )
+ {
+ sal_Int32 nLen = aNewArgs.getLength();
+ aNewArgs.realloc( nLen + 1 );
+
+ beans::PropertyValue aProp;
+ aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CFGPROPERTY_LAZYWRITE ) );
+ aProp.Value <<= sal_True;
+ aNewArgs[ nLen ] <<= aProp;
+ }
+
+ // Create configuration read-write access object.
+ xConfigAccess = xProv->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_READWRITE_SERVICE_NAME ) ),
+ aNewArgs );
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Cannot instanciate configuration access!" );
+ throw;
+ }
+
+ if ( !xConfigAccess.is() )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createInstanceWithArguments - "
+ "Cannot instanciate configuration access!" );
+ return xConfigAccess;
+ }
+
+ return uno::Reference< uno::XInterface >(
+ static_cast< cppu::OWeakObject * >(
+ new HierarchyDataAccess( xConfigAccess, bReadOnly ) ) );
+}
+
+//=========================================================================
+uno::Reference< lang::XMultiServiceFactory >
+HierarchyDataSource::getConfigProvider()
+{
+ if ( !m_xConfigProvider.is() )
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ if ( !m_xConfigProvider.is() )
+ {
+ try
+ {
+ m_xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ CONFIG_PROVIDER_SERVICE_NAME ) ) ),
+ uno::UNO_QUERY );
+
+ OSL_ENSURE( m_xConfigProvider.is(),
+ "HierarchyDataSource::getConfigProvider - "
+ "No configuration provider!" );
+ }
+ catch ( uno::Exception const & )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::getConfigProvider - "
+ "caught exception!" );
+ }
+ }
+ }
+
+ return m_xConfigProvider;
+}
+
+//=========================================================================
+bool HierarchyDataSource::createConfigPath(
+ const rtl::OUString & rInPath, rtl::OUString & rOutPath )
+{
+ if ( rInPath.getLength() )
+ {
+ if ( rInPath.indexOf( '/' ) == 0 )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createConfigPath - "
+ "Leading slash in node path!" );
+ return false;
+ }
+
+ if ( rInPath.lastIndexOf( '/' ) == rInPath.getLength() - 1 )
+ {
+ OSL_ENSURE( false,
+ "HierarchyDataSource::createConfigPath - "
+ "Trailing slash in node path!" );
+ return false;
+ }
+
+ rtl::OUString aOutPath(
+ RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY "/" ) );
+ aOutPath += rInPath;
+ rOutPath = aOutPath;
+ }
+ else
+ {
+ rOutPath = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
+ }
+
+ return true;
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyDataAccess Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+#define ENSURE_ORIG_INTERFACE( interface_name, member_name ) \
+ m_xCfg##member_name; \
+ if ( !m_xCfg##member_name.is() ) \
+ { \
+ osl::Guard< osl::Mutex > aGuard( m_aMutex ); \
+ if ( !m_xCfg##member_name.is() ) \
+ m_xCfg##member_name \
+ = uno::Reference< interface_name >( \
+ m_xConfigAccess, uno::UNO_QUERY ); \
+ xOrig = m_xCfg##member_name; \
+ }
+
+//=========================================================================
+HierarchyDataAccess::HierarchyDataAccess( const uno::Reference<
+ uno::XInterface > & xConfigAccess,
+ bool bReadOnly )
+: m_xConfigAccess( xConfigAccess ),
+ m_bReadOnly( bReadOnly )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyDataAccess::~HierarchyDataAccess()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_COMMON_IMPL( HierarchyDataAccess );
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::queryInterface( const uno::Type & aType )
+ throw ( uno::RuntimeException )
+{
+ // Interfaces supported in read-only and read-write mode.
+ uno::Any aRet = cppu::queryInterface( aType,
+ static_cast< lang::XTypeProvider * >( this ),
+ static_cast< lang::XServiceInfo * >( this ),
+ static_cast< lang::XComponent * >( this ),
+ static_cast< container::XHierarchicalNameAccess * >( this ),
+ static_cast< container::XNameAccess * >( this ),
+ static_cast< container::XElementAccess * >( this ),
+ static_cast< util::XChangesNotifier * >( this ) );
+
+ // Interfaces supported only in read-write mode.
+ if ( !aRet.hasValue() && !m_bReadOnly )
+ {
+ aRet = cppu::queryInterface( aType,
+ static_cast< lang::XSingleServiceFactory * >( this ),
+ static_cast< container::XNameContainer * >( this ),
+ static_cast< container::XNameReplace * >( this ),
+ static_cast< util::XChangesBatch * >( this ) );
+ }
+
+ return aRet.hasValue() ? aRet : OWeakObject::queryInterface( aType );
+}
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_COMMON_IMPL( HierarchyDataAccess );
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Type > SAL_CALL HierarchyDataAccess::getTypes()
+ throw( uno::RuntimeException )
+{
+ cppu::OTypeCollection * pCollection = 0;
+
+ if ( m_bReadOnly )
+ {
+ static cppu::OTypeCollection* pReadOnlyTypes = 0;
+
+ pCollection = pReadOnlyTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pReadOnlyTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
+ CPPU_TYPE_REF( container::XNameAccess ),
+ CPPU_TYPE_REF( util::XChangesNotifier ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pReadOnlyTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+ else
+ {
+ static cppu::OTypeCollection* pReadWriteTypes = 0;
+
+ pCollection = pReadWriteTypes;
+ if ( !pCollection )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+
+ pCollection = pReadWriteTypes;
+ if ( !pCollection )
+ {
+ static cppu::OTypeCollection aCollection(
+ CPPU_TYPE_REF( lang::XTypeProvider ),
+ CPPU_TYPE_REF( lang::XServiceInfo ),
+ CPPU_TYPE_REF( lang::XComponent ),
+ CPPU_TYPE_REF( lang::XSingleServiceFactory ),
+ CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
+ CPPU_TYPE_REF( container::XNameContainer ),
+ CPPU_TYPE_REF( util::XChangesBatch ),
+ CPPU_TYPE_REF( util::XChangesNotifier ) );
+ pCollection = &aCollection;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ pReadWriteTypes = pCollection;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ }
+
+ return (*pCollection).getTypes();
+}
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_NOFACTORY_IMPL_0(
+ HierarchyDataAccess,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.ucb.HierarchyDataAccess" ) ) )
+{
+ uno::Sequence< rtl::OUString > aSNS( 2 );
+ aSNS[ 0 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
+ aSNS[ 1 ] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
+ return aSNS;
+}
+
+//=========================================================================
+//
+// XComponent methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::dispose()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->dispose();
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->addEventListener( xListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::removeEventListener(
+ const uno::Reference< lang::XEventListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XComponent > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XComponent!" );
+ xOrig->removeEventListener( aListener );
+}
+
+//=========================================================================
+//
+// XHierarchicalNameAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::getByHierarchicalName(
+ const rtl::OUString & aName )
+ throw ( container::NoSuchElementException, uno::RuntimeException )
+{
+ uno::Reference< container::XHierarchicalNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : "
+ "Data source is not an XHierarchicalNameAccess!" );
+ return xOrig->getByHierarchicalName( aName );
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasByHierarchicalName(
+ const rtl::OUString & aName )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XHierarchicalNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : "
+ "Data source is not an XHierarchicalNameAccess!" );
+ return xOrig->hasByHierarchicalName( aName );
+}
+
+//=========================================================================
+//
+// XNameAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL HierarchyDataAccess::getByName( const rtl::OUString & aName )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->getByName( aName );
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< rtl::OUString > SAL_CALL HierarchyDataAccess::getElementNames()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->getElementNames();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasByName( const rtl::OUString & aName )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XNameAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameAccess!" );
+ return xOrig->hasByName( aName );
+}
+
+//=========================================================================
+//
+// XElementAccess methods.
+//
+//=========================================================================
+
+// virtual
+uno::Type SAL_CALL HierarchyDataAccess::getElementType()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XElementAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XElementAccess!" );
+ return xOrig->getElementType();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasElements()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< container::XElementAccess > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XElementAccess!" );
+ return xOrig->hasElements();
+}
+
+//=========================================================================
+//
+// XChangesNotifier methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::addChangesListener(
+ const uno::Reference< util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesNotifier > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
+ xOrig->addChangesListener( aListener );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL HierarchyDataAccess::removeChangesListener(
+ const uno::Reference< util::XChangesListener > & aListener )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesNotifier > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
+ xOrig->removeChangesListener( aListener );
+}
+
+//=========================================================================
+//
+// XSingleServiceFactory methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL HierarchyDataAccess::createInstance()
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ uno::Reference< lang::XSingleServiceFactory > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
+ return xOrig->createInstance();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< uno::XInterface > SAL_CALL
+HierarchyDataAccess::createInstanceWithArguments(
+ const uno::Sequence< uno::Any > & aArguments )
+ throw ( uno::Exception, uno::RuntimeException )
+{
+ uno::Reference< lang::XSingleServiceFactory > xOrig
+ = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
+ return xOrig->createInstanceWithArguments( aArguments );
+}
+
+//=========================================================================
+//
+// XNameContainer methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL
+HierarchyDataAccess::insertByName( const rtl::OUString & aName,
+ const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::ElementExistException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameContainer > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameContainer!" );
+ xOrig->insertByName( aName, aElement );
+}
+
+//=========================================================================
+// virtual
+void SAL_CALL
+HierarchyDataAccess::removeByName( const rtl::OUString & Name )
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameContainer > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameContainer!" );
+ xOrig->removeByName( Name );
+}
+
+//=========================================================================
+//
+// XNameReplace methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::replaceByName( const rtl::OUString & aName,
+ const uno::Any & aElement )
+ throw ( lang::IllegalArgumentException,
+ container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< container::XNameReplace > xOrig
+ = ENSURE_ORIG_INTERFACE( container::XNameReplace, NR );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XNameReplace!" );
+ xOrig->replaceByName( aName, aElement );
+}
+
+//=========================================================================
+//
+// XChangesBatch methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyDataAccess::commitChanges()
+ throw ( lang::WrappedTargetException, uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ xOrig->commitChanges();
+}
+
+//=========================================================================
+// virtual
+sal_Bool SAL_CALL HierarchyDataAccess::hasPendingChanges()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ return xOrig->hasPendingChanges();
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< util::ElementChange > SAL_CALL
+HierarchyDataAccess::getPendingChanges()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XChangesBatch > xOrig
+ = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
+
+ OSL_ENSURE( xOrig.is(),
+ "HierarchyDataAccess : Data source is not an XChangesBatch!" );
+ return xOrig->getPendingChanges();
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasource.hxx b/ucb/source/ucp/hierarchy/hierarchydatasource.hxx
new file mode 100644
index 000000000000..329011e142db
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasource.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYDATASOURCE_HXX
+#define _HIERARCHYDATASOURCE_HXX
+
+#include <osl/mutex.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <cppuhelper/weak.hxx>
+#include <ucbhelper/macros.hxx>
+
+namespace cppu { class OInterfaceContainerHelper; }
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+class HierarchyDataSource : public cppu::OWeakObject,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::lang::XMultiServiceFactory
+{
+ osl::Mutex m_aMutex;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider;
+ cppu::OInterfaceContainerHelper * m_pDisposeEventListeners;
+
+public:
+ HierarchyDataSource( const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &
+ rxServiceMgr );
+ virtual ~HierarchyDataSource();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XComponent
+ 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 );
+
+ // XMultiServiceFactory
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstance( const rtl::OUString & aServiceSpecifier )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const rtl::OUString & ServiceSpecifier,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any > & Arguments )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getAvailableServiceNames()
+ throw ( com::sun::star::uno::RuntimeException );
+
+ // Non-Interface methods
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const rtl::OUString & ServiceSpecifier,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::Any > & Arguments,
+ bool bCheckArgs )
+ throw ( com::sun::star::uno::Exception,
+ com::sun::star::uno::RuntimeException );
+
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >
+ getConfigProvider();
+
+ bool
+ createConfigPath( const rtl::OUString & rInPath, rtl::OUString & rOutPath );
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYDATASOURCE_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx b/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx
new file mode 100644
index 000000000000..8cd53a4a6201
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasupplier.cxx
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * 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 <ucbhelper/contentidentifier.hxx>
+#include "hierarchydatasupplier.hxx"
+#include "hierarchyprovider.hxx"
+#include "hierarchycontent.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+namespace hierarchy_ucp
+{
+
+//=========================================================================
+//
+// struct ResultListEntry.
+//
+//=========================================================================
+
+struct ResultListEntry
+{
+ rtl::OUString aId;
+ uno::Reference< ucb::XContentIdentifier > xId;
+ uno::Reference< ucb::XContent > xContent;
+ uno::Reference< sdbc::XRow > xRow;
+ HierarchyEntryData aData;
+
+ ResultListEntry( const HierarchyEntryData& rEntry ) : aData( rEntry ) {}
+};
+
+//=========================================================================
+//
+// ResultList.
+//
+//=========================================================================
+
+typedef std::vector< ResultListEntry* > ResultList;
+
+//=========================================================================
+//
+// struct DataSupplier_Impl.
+//
+//=========================================================================
+
+struct DataSupplier_Impl
+{
+ osl::Mutex m_aMutex;
+ ResultList m_aResults;
+ rtl::Reference< HierarchyContent > m_xContent;
+ uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
+ HierarchyEntry m_aFolder;
+ HierarchyEntry::iterator m_aIterator;
+ sal_Int32 m_nOpenMode;
+ sal_Bool m_bCountFinal;
+
+ DataSupplier_Impl(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode )
+ : m_xContent( rContent ), m_xSMgr( rxSMgr ),
+ m_aFolder( rxSMgr,
+ static_cast< HierarchyContentProvider * >(
+ rContent->getProvider().get() ),
+ rContent->getIdentifier()->getContentIdentifier() ),
+ m_nOpenMode( nOpenMode ), m_bCountFinal( sal_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++;
+ }
+}
+
+}
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyResultSetDataSupplier Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
+ const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode )
+: m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+// virtual
+rtl::OUString HierarchyResultSetDataSupplier::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 ]->aId;
+ if ( aId.getLength() )
+ {
+ // Already cached.
+ return aId;
+ }
+ }
+
+ if ( getResult( nIndex ) )
+ {
+ rtl::OUString aId
+ = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
+
+ if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
+ aId += rtl::OUString::createFromAscii( "/" );
+
+ aId += m_pImpl->m_aResults[ nIndex ]->aData.getName();
+
+ m_pImpl->m_aResults[ nIndex ]->aId = aId;
+ return aId;
+ }
+ return rtl::OUString();
+}
+
+//=========================================================================
+// virtual
+uno::Reference< ucb::XContentIdentifier >
+HierarchyResultSetDataSupplier::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 >
+HierarchyResultSetDataSupplier::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 HierarchyResultSetDataSupplier::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();
+ sal_Bool bFound = sal_False;
+ sal_uInt32 nPos = nOldCount;
+
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ {
+ const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
+ if ( checkResult( rResult ) )
+ {
+ m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
+
+ if ( nPos == nIndex )
+ {
+ // Result obtained.
+ bFound = sal_True;
+ break;
+ }
+ }
+ nPos++;
+ }
+
+ 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 HierarchyResultSetDataSupplier::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();
+
+ while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
+ {
+ const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
+ if ( checkResult( rResult ) )
+ m_pImpl->m_aResults.push_back( new ResultListEntry( rResult ) );
+ }
+
+ 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 HierarchyResultSetDataSupplier::currentCount()
+{
+ return m_pImpl->m_aResults.size();
+}
+
+//=========================================================================
+// virtual
+sal_Bool HierarchyResultSetDataSupplier::isCountFinal()
+{
+ return m_pImpl->m_bCountFinal;
+}
+
+//=========================================================================
+// virtual
+uno::Reference< sdbc::XRow >
+HierarchyResultSetDataSupplier::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 ) )
+ {
+ static rtl::OUString aFolderType(
+ rtl::OUString::createFromAscii( HIERARCHY_FOLDER_CONTENT_TYPE ) );
+ static rtl::OUString aLinkType(
+ rtl::OUString::createFromAscii( HIERARCHY_LINK_CONTENT_TYPE ) );
+
+ HierarchyContentProperties aData(
+ m_pImpl->m_aResults[ nIndex ]->aData );
+
+ uno::Reference< sdbc::XRow > xRow
+ = HierarchyContent::getPropertyValues(
+ m_pImpl->m_xSMgr,
+ getResultSet()->getProperties(),
+ aData,
+ static_cast< HierarchyContentProvider * >(
+ m_pImpl->m_xContent->getProvider().get() ),
+ queryContentIdentifierString( nIndex ) );
+ m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
+ return xRow;
+ }
+
+ return uno::Reference< sdbc::XRow >();
+}
+
+//=========================================================================
+// virtual
+void HierarchyResultSetDataSupplier::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 HierarchyResultSetDataSupplier::close()
+{
+}
+
+//=========================================================================
+// virtual
+void HierarchyResultSetDataSupplier::validate()
+ throw( ucb::ResultSetException )
+{
+}
+
+//=========================================================================
+sal_Bool HierarchyResultSetDataSupplier::checkResult(
+ const HierarchyEntryData& rResult )
+{
+ switch ( m_pImpl->m_nOpenMode )
+ {
+ case ucb::OpenMode::FOLDERS:
+ if ( rResult.getType() == HierarchyEntryData::LINK )
+ {
+ // Entry is a link.
+ return sal_False;
+ }
+ break;
+
+ case ucb::OpenMode::DOCUMENTS:
+ if ( rResult.getType() == HierarchyEntryData::FOLDER )
+ {
+ // Entry is a folder.
+ return sal_False;
+ }
+ break;
+
+ case ucb::OpenMode::ALL:
+ default:
+ break;
+ }
+
+ return sal_True;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx b/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx
new file mode 100644
index 000000000000..87218e0729d0
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchydatasupplier.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYDATASUPPLIER_HXX
+#define _HIERARCHYDATASUPPLIER_HXX
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/ucb/OpenMode.hpp>
+#include <ucbhelper/resultset.hxx>
+
+namespace hierarchy_ucp {
+
+class HierarchyEntryData;
+struct DataSupplier_Impl;
+class HierarchyContent;
+
+class HierarchyResultSetDataSupplier :
+ public ::ucbhelper::ResultSetDataSupplier
+{
+ DataSupplier_Impl* m_pImpl;
+
+private:
+ sal_Bool checkResult( const HierarchyEntryData& rResult );
+
+public:
+ HierarchyResultSetDataSupplier(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+ const rtl::Reference< HierarchyContent >& rContent,
+ sal_Int32 nOpenMode = com::sun::star::ucb::OpenMode::ALL );
+ virtual ~HierarchyResultSetDataSupplier();
+
+ 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 hierarchy_ucp
+
+#endif /* !_HIERARCHYDATASUPPLIER_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchyprovider.cxx b/ucb/source/ucp/hierarchy/hierarchyprovider.cxx
new file mode 100644
index 000000000000..5ce8ea891f51
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyprovider.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * 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
+ **************************************************************************
+
+ - XInitialization::initialize does not work any longer!
+
+ *************************************************************************/
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
+#include <ucbhelper/contentidentifier.hxx>
+#include "hierarchyprovider.hxx"
+#include "hierarchycontent.hxx"
+#include "hierarchyuri.hxx"
+
+#include "../inc/urihelper.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_ucp;
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyContentProvider Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+HierarchyContentProvider::HierarchyContentProvider(
+ const uno::Reference< lang::XMultiServiceFactory >& rXSMgr )
+: ::ucbhelper::ContentProviderImplHelper( rXSMgr )
+{
+}
+
+//=========================================================================
+// virtual
+HierarchyContentProvider::~HierarchyContentProvider()
+{
+}
+
+//=========================================================================
+//
+// XInterface methods.
+//
+//=========================================================================
+
+XINTERFACE_IMPL_4( HierarchyContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ lang::XInitialization );
+
+//=========================================================================
+//
+// XTypeProvider methods.
+//
+//=========================================================================
+
+XTYPEPROVIDER_IMPL_4( HierarchyContentProvider,
+ lang::XTypeProvider,
+ lang::XServiceInfo,
+ ucb::XContentProvider,
+ lang::XInitialization );
+
+//=========================================================================
+//
+// XServiceInfo methods.
+//
+//=========================================================================
+
+XSERVICEINFO_IMPL_1( HierarchyContentProvider,
+ rtl::OUString::createFromAscii(
+ "com.sun.star.comp.ucb.HierarchyContentProvider" ),
+ rtl::OUString::createFromAscii(
+ HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME ) );
+
+//=========================================================================
+//
+// Service factory implementation.
+//
+//=========================================================================
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyContentProvider );
+
+//=========================================================================
+//
+// XContentProvider methods.
+//
+//=========================================================================
+
+// virtual
+uno::Reference< ucb::XContent > SAL_CALL
+HierarchyContentProvider::queryContent(
+ const uno::Reference< ucb::XContentIdentifier >& Identifier )
+ throw( ucb::IllegalIdentifierException, uno::RuntimeException )
+{
+ HierarchyUri aUri( Identifier->getContentIdentifier() );
+ if ( !aUri.isValid() )
+ throw ucb::IllegalIdentifierException();
+
+ // Encode URL and create new Id. This may "correct" user-typed-in URL's.
+ uno::Reference< ucb::XContentIdentifier > xCanonicId
+ = new ::ucbhelper::ContentIdentifier( m_xSMgr,
+ ::ucb_impl::urihelper::encodeURI(
+ 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() )
+ return xContent;
+
+ // Create a new content.
+ xContent = HierarchyContent::create( m_xSMgr, this, xCanonicId );
+ registerNewContent( xContent );
+
+ if ( xContent.is() && !xContent->getIdentifier().is() )
+ throw ucb::IllegalIdentifierException();
+
+ return xContent;
+}
+
+//=========================================================================
+//
+// XInitialization methods.
+//
+//=========================================================================
+
+// virtual
+void SAL_CALL HierarchyContentProvider::initialize(
+ const uno::Sequence< uno::Any >& aArguments )
+ throw( uno::Exception, uno::RuntimeException )
+{
+#if 0
+ if ( aArguments.getLength() > 0 )
+ {
+ // Extract config provider from service init args.
+ aArguments[ 0 ] >>= m_xConfigProvider;
+
+ OSL_ENSURE( m_xConfigProvider.is(),
+ "HierarchyContentProvider::initialize - "
+ "No config provider!" );
+ }
+#else
+ if ( aArguments.getLength() > 0 )
+ OSL_ENSURE( false,
+ "HierarchyContentProvider::initialize : not supported!" );
+#endif
+}
+
+//=========================================================================
+//
+// Non-interface methods.
+//
+//=========================================================================
+
+uno::Reference< lang::XMultiServiceFactory >
+HierarchyContentProvider::getConfigProvider(
+ const rtl::OUString & rServiceSpecifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
+ rServiceSpecifier );
+ if ( it == m_aConfigProviderMap.end() )
+ {
+ try
+ {
+ ConfigProviderMapEntry aEntry;
+ aEntry.xConfigProvider
+ = uno::Reference< lang::XMultiServiceFactory >(
+ m_xSMgr->createInstance( rServiceSpecifier ),
+ uno::UNO_QUERY );
+
+ if ( aEntry.xConfigProvider.is() )
+ {
+ m_aConfigProviderMap[ rServiceSpecifier ] = aEntry;
+ return aEntry.xConfigProvider;
+ }
+ }
+ catch ( uno::Exception const & )
+ {
+// OSL_ENSURE( sal_False,
+// "HierarchyContentProvider::getConfigProvider - "
+// "caught exception!" );
+ }
+
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getConfigProvider - "
+ "No config provider!" );
+
+ return uno::Reference< lang::XMultiServiceFactory >();
+ }
+
+ return (*it).second.xConfigProvider;
+}
+
+//=========================================================================
+uno::Reference< container::XHierarchicalNameAccess >
+HierarchyContentProvider::getRootConfigReadNameAccess(
+ const rtl::OUString & rServiceSpecifier )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ ConfigProviderMap::iterator it = m_aConfigProviderMap.find(
+ rServiceSpecifier );
+ if ( it != m_aConfigProviderMap.end() )
+ {
+ if ( !( (*it).second.xRootReadAccess.is() ) )
+ {
+ if ( (*it).second.bTriedToGetRootReadAccess ) // #82494#
+ {
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getRootConfigReadNameAccess - "
+ "Unable to read any config data! -> #82494#" );
+ return uno::Reference< container::XHierarchicalNameAccess >();
+ }
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProv
+ = getConfigProvider( rServiceSpecifier );
+
+ if ( xConfigProv.is() )
+ {
+ uno::Sequence< uno::Any > aArguments( 1 );
+ beans::PropertyValue aProperty;
+ aProperty.Name
+ = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aProperty.Value <<= rtl::OUString(); // root path
+ aArguments[ 0 ] <<= aProperty;
+
+ (*it).second.bTriedToGetRootReadAccess = true;
+
+ (*it).second.xRootReadAccess
+ = uno::Reference< container::XHierarchicalNameAccess >(
+ xConfigProv->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.ucb."
+ "HierarchyDataReadAccess" ) ),
+ aArguments ),
+ uno::UNO_QUERY );
+ }
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ throw;
+ }
+ catch ( uno::Exception const & )
+ {
+ // createInstance, createInstanceWithArguments
+
+ OSL_ENSURE( sal_False,
+ "HierarchyContentProvider::getRootConfigReadNameAccess - "
+ "caught Exception!" );
+ }
+ }
+ }
+
+ return (*it).second.xRootReadAccess;
+}
+
+//=========================================================================
+uno::Reference< util::XOfficeInstallationDirectories >
+HierarchyContentProvider::getOfficeInstallationDirectories()
+{
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_xOfficeInstDirs.is() )
+ {
+ OSL_ENSURE( m_xSMgr.is(), "No service manager!" );
+
+ uno::Reference< uno::XComponentContext > xCtx;
+ uno::Reference< beans::XPropertySet > xPropSet(
+ m_xSMgr, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
+ >>= xCtx;
+ }
+
+ OSL_ENSURE( xCtx.is(),
+ "Unable to obtain component context from "
+ "service manager!" );
+
+ if ( xCtx.is() )
+ {
+ xCtx->getValueByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/"
+ "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
+ >>= m_xOfficeInstDirs;
+
+// Be silent. singleton only available in an Office environment.
+// OSL_ENSURE( m_xOfficeInstDirs.is(),
+// "Unable to obtain office directories singleton!" );
+ }
+ }
+ }
+ return m_xOfficeInstDirs;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyprovider.hxx b/ucb/source/ucp/hierarchy/hierarchyprovider.hxx
new file mode 100644
index 000000000000..9212aadf417e
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyprovider.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYPROVIDER_HXX
+#define _HIERARCHYPROVIDER_HXX
+
+#include <hash_map>
+#include <ucbhelper/providerhelper.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace util {
+ class XOfficeInstallationDirectories;
+ }
+} } }
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+#define HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME \
+ "com.sun.star.ucb.HierarchyContentProvider"
+#define HIERARCHY_CONTENT_PROVIDER_SERVICE_NAME_LENGTH 41
+
+#define HIERARCHY_URL_SCHEME \
+ "vnd.sun.star.hier"
+#define HIERARCHY_URL_SCHEME_LENGTH 17
+
+#define HIERARCHY_FOLDER_CONTENT_TYPE \
+ "application/" HIERARCHY_URL_SCHEME "-folder"
+#define HIERARCHY_LINK_CONTENT_TYPE \
+ "application/" HIERARCHY_URL_SCHEME "-link"
+
+//=========================================================================
+
+struct ConfigProviderMapEntry
+{
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > xConfigProvider;
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > xRootReadAccess;
+ bool bTriedToGetRootReadAccess; // #82494#
+
+ ConfigProviderMapEntry() : bTriedToGetRootReadAccess( false ) {}
+};
+
+struct equalString
+{
+ bool operator()(
+ const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
+ {
+ return !!( rKey1 == rKey2 );
+ }
+};
+
+struct hashString
+{
+ size_t operator()( const rtl::OUString & rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+typedef std::hash_map
+<
+ rtl::OUString, // servcie specifier
+ ConfigProviderMapEntry,
+ hashString,
+ equalString
+>
+ConfigProviderMap;
+
+//=========================================================================
+
+class HierarchyContentProvider : public ::ucbhelper::ContentProviderImplHelper,
+ public com::sun::star::lang::XInitialization
+{
+ ConfigProviderMap m_aConfigProviderMap;
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
+
+public:
+ HierarchyContentProvider(
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rXSMgr );
+ virtual ~HierarchyContentProvider();
+
+ // 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 );
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Any >& aArguments )
+ throw( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException );
+
+ // Non-Interface methods
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >
+ getConfigProvider( const rtl::OUString & rServiceSpecifier );
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess >
+ getRootConfigReadNameAccess( const rtl::OUString & rServiceSpecifier );
+
+ // Note: may retrun an empty reference.
+ com::sun::star::uno::Reference<
+ com::sun::star::util::XOfficeInstallationDirectories >
+ getOfficeInstallationDirectories();
+};
+
+} // namespace hierarchy_ucp
+
+#endif /* !_HIERARCHYPROVIDER_HXX */
diff --git a/ucb/source/ucp/hierarchy/hierarchyservices.cxx b/ucb/source/ucp/hierarchy/hierarchyservices.cxx
new file mode 100644
index 000000000000..e645e006032e
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyservices.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * 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 "hierarchyprovider.hxx"
+#include "hierarchydatasource.hxx"
+
+using namespace com::sun::star;
+using namespace hierarchy_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 &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ HierarchyContentProvider::getImplementationName_Static(),
+ HierarchyContentProvider::getSupportedServiceNames_Static() ) &&
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Data Source.
+ //////////////////////////////////////////////////////////////////////
+
+ writeInfo( pRegistryKey,
+ HierarchyDataSource::getImplementationName_Static(),
+ HierarchyDataSource::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;
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Content Provider.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( HierarchyContentProvider::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = HierarchyContentProvider::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Hierarchy Data Source.
+ //////////////////////////////////////////////////////////////////////
+
+ else if ( HierarchyDataSource::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = HierarchyDataSource::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyuri.cxx b/ucb/source/ucp/hierarchy/hierarchyuri.cxx
new file mode 100644
index 000000000000..0621db72d5bb
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyuri.cxx
@@ -0,0 +1,209 @@
+/*************************************************************************
+ *
+ * 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 "osl/diagnose.h"
+
+#include "hierarchyuri.hxx"
+
+using namespace hierarchy_ucp;
+
+//=========================================================================
+
+#define DEFAULT_DATA_SOURCE_SERVICE \
+ "com.sun.star.ucb.DefaultHierarchyDataSource"
+
+//=========================================================================
+//=========================================================================
+//
+// HierarchyUri Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+void HierarchyUri::init() const
+{
+ // Already inited?
+ if ( m_aUri.getLength() && !m_aPath.getLength() )
+ {
+ // Note: Maybe it's a re-init, setUri only resets m_aPath!
+ m_aService = m_aParentUri = m_aName = rtl::OUString();
+
+ // URI must match at least: <sheme>:
+ if ( ( m_aUri.getLength() < HIERARCHY_URL_SCHEME_LENGTH + 1 ) )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Scheme is case insensitive.
+ rtl::OUString aScheme
+ = m_aUri.copy( 0, HIERARCHY_URL_SCHEME_LENGTH ).toAsciiLowerCase();
+ if ( aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HIERARCHY_URL_SCHEME ) ) )
+ {
+ m_aUri = m_aUri.replaceAt( 0, aScheme.getLength(), aScheme );
+
+ sal_Int32 nPos = 0;
+
+ // If the URI has no service specifier, insert default service.
+ // This is for backward compatibility and for convenience.
+
+ if ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 1 )
+ {
+ // root folder URI without path and service specifier.
+ m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "//" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos = m_aUri.getLength() - 1;
+ }
+ else if ( ( m_aUri.getLength() == HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ &&
+ ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 1 ]
+ == sal_Unicode( '/' ) ) )
+ {
+ // root folder URI without service specifier.
+ m_aUri += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos = m_aUri.getLength() - 1;
+ }
+ else if ( ( m_aUri.getLength() > HIERARCHY_URL_SCHEME_LENGTH + 2 )
+ &&
+ ( m_aUri.getStr()[ HIERARCHY_URL_SCHEME_LENGTH + 2 ]
+ != sal_Unicode( '/' ) ) )
+ {
+ // other (no root folder) URI without service specifier.
+ m_aUri = m_aUri.replaceAt(
+ HIERARCHY_URL_SCHEME_LENGTH + 2,
+ 0,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/" DEFAULT_DATA_SOURCE_SERVICE "/" ) ) );
+ m_aService
+ = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ DEFAULT_DATA_SOURCE_SERVICE ) );
+
+ nPos
+ = HIERARCHY_URL_SCHEME_LENGTH + 3 + m_aService.getLength();
+ }
+ else
+ {
+ // URI with service specifier.
+ sal_Int32 nStart = HIERARCHY_URL_SCHEME_LENGTH + 3;
+
+ // Here: - m_aUri has at least the form "<scheme>://"
+ // - nStart points to char after <scheme>://
+
+ // Only <scheme>:// ?
+ if ( nStart == m_aUri.getLength() )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ // Empty path segments?
+ if ( m_aUri.indexOf(
+ rtl::OUString::createFromAscii( "//" ),
+ nStart ) != -1 )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ sal_Int32 nEnd = m_aUri.indexOf( '/', nStart );
+
+ // Only <scheme>:/// ?
+ if ( nEnd == nStart )
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ return;
+ }
+
+ if ( nEnd == -1 )
+ {
+ // Trailing slash missing.
+ nEnd = m_aUri.getLength();
+ m_aUri += rtl::OUString::createFromAscii( "/" );
+ }
+
+ m_aService = m_aUri.copy( nStart, nEnd - nStart );
+
+ nPos = nEnd;
+ }
+
+ // Here: - m_aUri has at least the form "<scheme>://<service>/"
+ // - m_aService was set
+ // - m_aPath, m_aParentPath, m_aName not yet set
+ // - nPos points to slash after service specifier
+
+ // Remove trailing slash, if not a root folder URI.
+ sal_Int32 nEnd = m_aUri.lastIndexOf( '/' );
+ if ( ( nEnd > nPos ) && ( nEnd == ( m_aUri.getLength() - 1 ) ) )
+ m_aUri = m_aUri.copy( 0, nEnd );
+
+ // Path (includes leading slash)
+ m_aPath = m_aUri.copy( nPos );
+
+ // parent URI + name
+ sal_Int32 nLastSlash = m_aUri.lastIndexOf( '/' );
+ if ( ( nLastSlash != -1 ) &&
+ ( nLastSlash != m_aUri.getLength() - 1 ) ) // root
+ {
+ m_aParentUri = m_aUri.copy( 0, nLastSlash );
+ m_aName = m_aUri.copy( nLastSlash + 1 );
+ }
+
+ // success
+ m_bValid = true;
+ }
+ else
+ {
+ // error, but remember that we did a init().
+ m_aPath = rtl::OUString::createFromAscii( "/" );
+ }
+ }
+}
+
diff --git a/ucb/source/ucp/hierarchy/hierarchyuri.hxx b/ucb/source/ucp/hierarchy/hierarchyuri.hxx
new file mode 100644
index 000000000000..012d59bb4cf2
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/hierarchyuri.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * 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 _HIERARCHYURI_HXX
+#define _HIERARCHYURI_HXX
+
+#include <rtl/ustring.hxx>
+
+namespace hierarchy_ucp {
+
+//=========================================================================
+
+#define HIERARCHY_URL_SCHEME "vnd.sun.star.hier"
+#define HIERARCHY_URL_SCHEME_LENGTH 17
+
+//=========================================================================
+
+class HierarchyUri
+{
+ mutable ::rtl::OUString m_aUri;
+ mutable ::rtl::OUString m_aParentUri;
+ mutable ::rtl::OUString m_aService;
+ mutable ::rtl::OUString m_aPath;
+ mutable ::rtl::OUString m_aName;
+ mutable bool m_bValid;
+
+private:
+ void init() const;
+
+public:
+ HierarchyUri() : m_bValid( false ) {}
+ HierarchyUri( const ::rtl::OUString & rUri )
+ : m_aUri( rUri ), m_bValid( false ) {}
+
+ sal_Bool isValid() const
+ { init(); return m_bValid; }
+
+ const ::rtl::OUString & getUri() const
+ { init(); return m_aUri; }
+
+ void setUri( const ::rtl::OUString & rUri )
+ { m_aPath = ::rtl::OUString(); m_aUri = rUri; m_bValid = false; }
+
+ const ::rtl::OUString & getParentUri() const
+ { init(); return m_aParentUri; }
+
+ const ::rtl::OUString & getService() const
+ { init(); return m_aService; }
+
+ const ::rtl::OUString & getPath() const
+ { init(); return m_aPath; }
+
+ const ::rtl::OUString & getName() const
+ { init(); return m_aName; }
+
+ inline sal_Bool isRootFolder() const;
+};
+
+inline sal_Bool HierarchyUri::isRootFolder() const
+{
+ init();
+ return ( ( m_aPath.getLength() == 1 ) &&
+ ( m_aPath.getStr()[ 0 ] == sal_Unicode( '/' ) ) );
+}
+}
+
+#endif
diff --git a/ucb/source/ucp/hierarchy/makefile.mk b/ucb/source/ucp/hierarchy/makefile.mk
new file mode 100644
index 000000000000..00b481b5e7a1
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# 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
+TARGET=ucphier
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+NO_BSYMBOLIC=TRUE
+
+# Version
+UCPHIER_MAJOR=1
+
+# --- Settings ---------------------------------------------------------
+
+.INCLUDE: settings.mk
+
+# --- General -----------------------------------------------------
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/hierarchyservices.obj \
+ $(SLO)$/hierarchydata.obj \
+ $(SLO)$/hierarchyprovider.obj \
+ $(SLO)$/hierarchycontent.obj \
+ $(SLO)$/hierarchycontentcaps.obj \
+ $(SLO)$/hierarchydatasupplier.obj \
+ $(SLO)$/dynamicresultset.obj \
+ $(SLO)$/hierarchydatasource.obj \
+ $(SLO)$/hierarchyuri.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+# --- Shared-Library ---------------------------------------------------
+
+SHL1TARGET=$(TARGET)$(UCPHIER_MAJOR)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(UCBHELPERLIB)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+
+# --- Def-File ---------------------------------------------------------
+
+DEF1NAME=$(SHL1TARGET)
+
+# --- Targets ----------------------------------------------------------
+
+.ENDIF # L10N_framework
+.INCLUDE: target.mk
+
diff --git a/ucb/source/ucp/hierarchy/ucphier.xml b/ucb/source/ucp/hierarchy/ucphier.xml
new file mode 100644
index 000000000000..1c63cbcbd7ee
--- /dev/null
+++ b/ucb/source/ucp/hierarchy/ucphier.xml
@@ -0,0 +1,121 @@
+<?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>
+ ucphier
+ </module-name>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.HierarchyContentProvider
+ </name>
+ <description>
+ This component implements a Content Provider for the Universal
+ Content Broker. It provides access to a persistent hierarchy of
+ folders and links.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.HierarchyContentProvider
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.DefaultHierarchyDataSource
+ </service-dependency>
+ <service-dependency>
+ com.sun.star.util.OfficeeInstallationDirectories
+ </service-dependency>
+ </component-description>
+
+ <component-description>
+ <author>
+ Kai Sommerfeld
+ </author>
+ <name>
+ com.sun.star.comp.ucb.HierarchyDataSource
+ </name>
+ <description>
+ This component implements a default data source for the Hierarchy
+ Content Provider. The data are accessed using the service
+ com.sun.star.configuration.ConfigurationProvider.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.DefaultHierarchyDataSource
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.configuration.ConfigurationProvider
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </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.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertiesChangeNotifier </type>
+ <type> com.sun.star.beans.XPropertyAccess </type>
+ <type> com.sun.star.beans.XPropertyContainer </type>
+ <type> com.sun.star.beans.XPropertySetInfoChangeNotifier </type>
+ <type> com.sun.star.container.XChild </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.lang.IllegalAccessException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XInitialization </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.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XColumnLocate </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </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.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.ResultSetException </type>
+ <type> com.sun.star.ucb.TransferInfo </type>
+ <type> com.sun.star.ucb.UnsuppertedNameClashException </type>
+ <type> com.sun.star.ucb.XCommandInfo </type>
+ <type> com.sun.star.ucb.XCommandInfoChangeNotifier </type>
+ <type> com.sun.star.ucb.XCommandProcessor </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XContentCreator </type>
+ <type> com.sun.star.ucb.XContentProvider </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XPersistentPropertySet </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.util.XChangesBatch </type>
+ <type> com.sun.star.util.XChangesNotifier </type>
+ <type> com.sun.star.util.XOfficeInstallationDirectories </type>
+</module-description>