diff options
Diffstat (limited to 'ucb/source/core')
-rw-r--r-- | ucb/source/core/cmdenv.cxx | 191 | ||||
-rw-r--r-- | ucb/source/core/cmdenv.hxx | 102 | ||||
-rw-r--r-- | ucb/source/core/exports2.dxp | 4 | ||||
-rw-r--r-- | ucb/source/core/identify.cxx | 116 | ||||
-rw-r--r-- | ucb/source/core/identify.hxx | 68 | ||||
-rw-r--r-- | ucb/source/core/makefile.mk | 84 | ||||
-rw-r--r-- | ucb/source/core/providermap.hxx | 77 | ||||
-rw-r--r-- | ucb/source/core/provprox.cxx | 401 | ||||
-rw-r--r-- | ucb/source/core/provprox.hxx | 166 | ||||
-rw-r--r-- | ucb/source/core/ucb.cxx | 959 | ||||
-rw-r--r-- | ucb/source/core/ucb.hxx | 220 | ||||
-rw-r--r-- | ucb/source/core/ucb.xml | 172 | ||||
-rw-r--r-- | ucb/source/core/ucb1.component | 46 | ||||
-rw-r--r-- | ucb/source/core/ucbcmds.cxx | 2090 | ||||
-rw-r--r-- | ucb/source/core/ucbcmds.hxx | 43 | ||||
-rw-r--r-- | ucb/source/core/ucbprops.cxx | 477 | ||||
-rw-r--r-- | ucb/source/core/ucbprops.hxx | 93 | ||||
-rw-r--r-- | ucb/source/core/ucbserv.cxx | 121 | ||||
-rw-r--r-- | ucb/source/core/ucbstore.cxx | 2770 | ||||
-rw-r--r-- | ucb/source/core/ucbstore.hxx | 345 |
20 files changed, 8545 insertions, 0 deletions
diff --git a/ucb/source/core/cmdenv.cxx b/ucb/source/core/cmdenv.cxx new file mode 100644 index 000000000000..5c0136fab063 --- /dev/null +++ b/ucb/source/core/cmdenv.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * 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 "cppuhelper/factory.hxx" +#include "com/sun/star/lang/IllegalArgumentException.hpp" + +#include "cmdenv.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +using namespace com::sun::star; +using namespace ucb_cmdenv; + +//========================================================================= +//========================================================================= +// +// UcbCommandEnvironment Implementation. +// +//========================================================================= +//========================================================================= + +UcbCommandEnvironment::UcbCommandEnvironment( + const uno::Reference< lang::XMultiServiceFactory >& /*xSMgr*/ ) +//: m_xSMgr( xSMgr ) +{ +} + +//========================================================================= +// virtual +UcbCommandEnvironment::~UcbCommandEnvironment() +{ +} + +//========================================================================= +// +// XInitialization methods. +// +//========================================================================= + +// virtual +void SAL_CALL UcbCommandEnvironment::initialize( + const uno::Sequence< uno::Any >& aArguments ) + throw( uno::Exception, + uno::RuntimeException ) +{ + if ( ( aArguments.getLength() < 2 ) || + !( aArguments[ 0 ] >>= m_xIH ) || + !( aArguments[ 1 ] >>= m_xPH )) + throw lang::IllegalArgumentException(); +} + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +// virtual +::rtl::OUString SAL_CALL UcbCommandEnvironment::getImplementationName() + throw ( uno::RuntimeException ) +{ + return getImplementationName_Static(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL +UcbCommandEnvironment::supportsService( const ::rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) +{ + uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames(); + const rtl::OUString * pArray = aSNL.getConstArray(); + for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + { + if ( pArray[ i ] == ServiceName ) + return sal_True; + } + return sal_False; +} + +//========================================================================= +// virtual +uno::Sequence< ::rtl::OUString > SAL_CALL +UcbCommandEnvironment::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + +//========================================================================= +// static +rtl::OUString UcbCommandEnvironment::getImplementationName_Static() +{ + return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.comp.ucb.CommandEnvironment" ) ); +} + +//========================================================================= +// static +uno::Sequence< rtl::OUString > +UcbCommandEnvironment::getSupportedServiceNames_Static() +{ + uno::Sequence< rtl::OUString > aSNS( 1 ); + aSNS.getArray()[ 0 ] + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ucb.CommandEnvironment" ) ); + return aSNS; +} + +//========================================================================= +// +// XCommandInfo methods. +// +//========================================================================= + +// virtual +uno::Reference< task::XInteractionHandler > SAL_CALL +UcbCommandEnvironment::getInteractionHandler() + throw ( uno::RuntimeException ) +{ + return m_xIH; +} + +//========================================================================= +// virtual +uno::Reference< ucb::XProgressHandler > SAL_CALL +UcbCommandEnvironment::getProgressHandler() + throw ( uno::RuntimeException ) +{ + return m_xPH; +} + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +static uno::Reference< uno::XInterface > SAL_CALL +UcbCommandEnvironment_CreateInstance( + const uno::Reference< lang::XMultiServiceFactory> & rSMgr ) + throw( uno::Exception ) +{ + lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >( + new UcbCommandEnvironment( rSMgr ) ); + return uno::Reference< uno::XInterface >::query( pX ); +} + +//========================================================================= +// static +uno::Reference< lang::XSingleServiceFactory > +UcbCommandEnvironment::createServiceFactory( + const uno::Reference< lang::XMultiServiceFactory >& rxServiceMgr ) +{ + return uno::Reference< lang::XSingleServiceFactory >( + cppu::createSingleFactory( + rxServiceMgr, + UcbCommandEnvironment::getImplementationName_Static(), + UcbCommandEnvironment_CreateInstance, + UcbCommandEnvironment::getSupportedServiceNames_Static() ) ); +} diff --git a/ucb/source/core/cmdenv.hxx b/ucb/source/core/cmdenv.hxx new file mode 100644 index 000000000000..419ce6afb560 --- /dev/null +++ b/ucb/source/core/cmdenv.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_CMDENV_HXX +#define INCLUDED_CMDENV_HXX + +#include "cppuhelper/implbase3.hxx" + +#include "com/sun/star/lang/XInitialization.hpp" +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/lang/XSingleServiceFactory.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" + +namespace ucb_cmdenv { + +class UcbCommandEnvironment : + public cppu::WeakImplHelper3< com::sun::star::lang::XInitialization, + com::sun::star::lang::XServiceInfo, + com::sun::star::ucb::XCommandEnvironment > +{ + com::sun::star::uno::Reference< + com::sun::star::task::XInteractionHandler > m_xIH; + com::sun::star::uno::Reference< + com::sun::star::ucb::XProgressHandler > m_xPH; + +public: + UcbCommandEnvironment( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rXSMgr ); + virtual ~UcbCommandEnvironment(); + + // 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 ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw ( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& ServiceName ) + throw ( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw ( com::sun::star::uno::RuntimeException ); + + // XCommandEnvironment + virtual com::sun::star::uno::Reference< + com::sun::star::task::XInteractionHandler > SAL_CALL + getInteractionHandler() + throw ( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XProgressHandler > SAL_CALL + getProgressHandler() + throw ( com::sun::star::uno::RuntimeException ); + + // Non-UNO interfaces + static rtl::OUString + getImplementationName_Static(); + static com::sun::star::uno::Sequence< rtl::OUString > + getSupportedServiceNames_Static(); + + static com::sun::star::uno::Reference< + com::sun::star::lang::XSingleServiceFactory > + createServiceFactory( const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > & rxServiceMgr ); +private: + //com::sun::star::uno::Reference< + // com::sun::star::lang::XMultiServiceFactory > m_xSMgr; +}; + +} // namespace ucb_cmdenv + +#endif // INCLUDED_CMDENV_HXX diff --git a/ucb/source/core/exports2.dxp b/ucb/source/core/exports2.dxp new file mode 100644 index 000000000000..8091459f4d84 --- /dev/null +++ b/ucb/source/core/exports2.dxp @@ -0,0 +1,4 @@ +component_getImplementationEnvironment +component_getFactory + +_ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE diff --git a/ucb/source/core/identify.cxx b/ucb/source/core/identify.cxx new file mode 100644 index 000000000000..ece9211c1ac3 --- /dev/null +++ b/ucb/source/core/identify.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * 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 "identify.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; + +//========================================================================= +// +// ContentIdentifier Implementation. +// +//========================================================================= + +ContentIdentifier::ContentIdentifier( + const Reference< XMultiServiceFactory >& rxSMgr, + const OUString& ContentId ) +: m_xSMgr( rxSMgr ), + m_aContentId( ContentId ) +{ +} + +//========================================================================= +// virtual +ContentIdentifier::~ContentIdentifier() +{ +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_2( ContentIdentifier, + XTypeProvider, + XContentIdentifier ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_2( ContentIdentifier, + XTypeProvider, + XContentIdentifier ); + +//========================================================================= +// +// XContentIdentifier methods. +// +//========================================================================= + +// virtual +OUString SAL_CALL ContentIdentifier::getContentIdentifier() + throw( RuntimeException ) +{ + return m_aContentId; +} + +//========================================================================= +// virtual +OUString SAL_CALL ContentIdentifier::getContentProviderScheme() + throw( RuntimeException ) +{ + if ( !m_aProviderScheme.getLength() && m_aContentId.getLength() ) + { + // The content provider scheme is the part before the first ':' + // within the content id. + sal_Int32 nPos = m_aContentId.indexOf( ':', 0 ); + if ( nPos != -1 ) + { + OUString aScheme( m_aContentId.copy( 0, nPos ) ); + m_aProviderScheme = aScheme.toAsciiLowerCase(); + } + } + + return m_aProviderScheme; +} + diff --git a/ucb/source/core/identify.hxx b/ucb/source/core/identify.hxx new file mode 100644 index 000000000000..d8ea23b1eee5 --- /dev/null +++ b/ucb/source/core/identify.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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 _IDENTIFY_HXX +#define _IDENTIFY_HXX + +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> + +//========================================================================= + +class ContentIdentifier : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::ucb::XContentIdentifier +{ +public: + ContentIdentifier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const rtl::OUString& ContentId ); + virtual ~ContentIdentifier(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XContentIdentifier + virtual rtl::OUString SAL_CALL getContentIdentifier() + throw( com::sun::star::uno::RuntimeException ); + virtual rtl::OUString SAL_CALL getContentProviderScheme() + throw( com::sun::star::uno::RuntimeException ); + +private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr; + rtl::OUString m_aContentId; + rtl::OUString m_aProviderScheme; +}; + +#endif /* !_IDENTIFY_HXX */ diff --git a/ucb/source/core/makefile.mk b/ucb/source/core/makefile.mk new file mode 100644 index 000000000000..6360f82320d2 --- /dev/null +++ b/ucb/source/core/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=ucb +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# Version +UCB_MAJOR=1 + +.INCLUDE: settings.mk +.IF "$(L10N_framework)"=="" + +SLOFILES=\ + $(SLO)$/identify.obj \ + $(SLO)$/ucb.obj \ + $(SLO)$/ucbserv.obj \ + $(SLO)$/ucbstore.obj \ + $(SLO)$/ucbprops.obj \ + $(SLO)$/provprox.obj \ + $(SLO)$/ucbcmds.obj \ + $(SLO)$/cmdenv.obj + +LIB1TARGET=$(SLB)$/_$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +SHL1TARGET=$(TARGET)$(UCB_MAJOR) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1STDLIBS=\ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) \ + $(UCBHELPERLIB) +SHL1LIBS=\ + $(LIB1TARGET) \ + $(SLB)$/regexp.lib +SHL1IMPLIB=i$(TARGET) + +.IF "$(GUI)" == "OS2" +DEF1EXPORTFILE=exports2.dxp +.ELSE +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +.ENDIF + +DEF1NAME=$(SHL1TARGET) + +.ENDIF # L10N_framework + +.INCLUDE: target.mk + + +ALLTAR : $(MISC)/ucb1.component + +$(MISC)/ucb1.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + ucb1.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt ucb1.component diff --git a/ucb/source/core/providermap.hxx b/ucb/source/core/providermap.hxx new file mode 100644 index 000000000000..a7fec30a42bf --- /dev/null +++ b/ucb/source/core/providermap.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * 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 _UCB_PROVIDERMAP_HXX_ +#define _UCB_PROVIDERMAP_HXX_ + +#include <list> +#include <com/sun/star/uno/Reference.h> +#include <regexpmap.hxx> + +namespace com { namespace sun { namespace star { namespace ucb { + class XContentProvider; +} } } } + +//============================================================================ +class ProviderListEntry_Impl +{ + com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > m_xProvider; + mutable com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > m_xResolvedProvider; + +private: + com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > resolveProvider() const; + +public: + ProviderListEntry_Impl( + const com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider >& xProvider ) + : m_xProvider( xProvider ) {} + + com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > getProvider() const + { return m_xProvider; } + inline com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > getResolvedProvider() const; +}; + +inline com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > +ProviderListEntry_Impl::getResolvedProvider() const +{ + return m_xResolvedProvider.is() ? m_xResolvedProvider : resolveProvider(); +} + +//============================================================================ +typedef std::list< ProviderListEntry_Impl > ProviderList_Impl; + +//============================================================================ +typedef ucb_impl::RegexpMap< ProviderList_Impl > ProviderMap_Impl; + +#endif // _UCB_PROVIDERMAP_HXX_ + diff --git a/ucb/source/core/provprox.cxx b/ucb/source/core/provprox.cxx new file mode 100644 index 000000000000..feab9ce4f95e --- /dev/null +++ b/ucb/source/core/provprox.cxx @@ -0,0 +1,401 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" +#include <osl/diagnose.h> +#include "provprox.hxx" +#include <com/sun/star/lang/XInitialization.hpp> + +using namespace rtl; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; + +//========================================================================= +//========================================================================= +// +// UcbContentProviderProxyFactory Implementation. +// +//========================================================================= +//========================================================================= + +UcbContentProviderProxyFactory::UcbContentProviderProxyFactory( + const Reference< XMultiServiceFactory >& rxSMgr ) +: m_xSMgr( rxSMgr ) +{ +} + +//========================================================================= +// virtual +UcbContentProviderProxyFactory::~UcbContentProviderProxyFactory() +{ +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_3( UcbContentProviderProxyFactory, + XTypeProvider, + XServiceInfo, + XContentProviderFactory ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_3( UcbContentProviderProxyFactory, + XTypeProvider, + XServiceInfo, + XContentProviderFactory ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_IMPL_1( UcbContentProviderProxyFactory, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UcbContentProviderProxyFactory" ), + OUString::createFromAscii( + PROVIDER_FACTORY_SERVICE_NAME ) ); + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbContentProviderProxyFactory ); + +//========================================================================= +// +// XContentProviderFactory methods. +// +//========================================================================= + +// virtual +Reference< XContentProvider > SAL_CALL +UcbContentProviderProxyFactory::createContentProvider( + const OUString& Service ) + throw( RuntimeException ) +{ + return Reference< XContentProvider >( + new UcbContentProviderProxy( m_xSMgr, Service ) ); +} + +//========================================================================= +//========================================================================= +// +// UcbContentProviderProxy Implementation. +// +//========================================================================= +//========================================================================= + +UcbContentProviderProxy::UcbContentProviderProxy( + const Reference< XMultiServiceFactory >& rxSMgr, + const OUString& Service ) +: m_aService( Service ), + m_bReplace( sal_False ), + m_bRegister( sal_False ), + m_xSMgr( rxSMgr ) +{ +} + +//========================================================================= +// virtual +UcbContentProviderProxy::~UcbContentProviderProxy() +{ +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_COMMON_IMPL( UcbContentProviderProxy ); + +//============================================================================ +// virtual +Any SAL_CALL +UcbContentProviderProxy::queryInterface( const Type & rType ) + throw ( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + static_cast< XTypeProvider * >( this ), + static_cast< XServiceInfo * >( this ), + static_cast< XContentProvider * >( this ), + static_cast< XParameterizedContentProvider * >( this ), + static_cast< XContentProviderSupplier * >( this ) ); + + if ( !aRet.hasValue() ) + aRet = OWeakObject::queryInterface( rType ); + + if ( !aRet.hasValue() ) + { + // Get original provider an forward the call... + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + Reference< XContentProvider > xProvider = getContentProvider(); + if ( xProvider.is() ) + aRet = xProvider->queryInterface( rType ); + } + + return aRet; +} + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_COMMON_IMPL( UcbContentProviderProxy ); + +//========================================================================= + +Sequence< Type > SAL_CALL UcbContentProviderProxy::getTypes() \ + throw( RuntimeException ) +{ + // Get original provider an forward the call... + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + Reference< XTypeProvider > xProvider( getContentProvider(), UNO_QUERY ); + if ( xProvider.is() ) + { + return xProvider->getTypes(); + } + else + { + static cppu::OTypeCollection collection( + CPPU_TYPE_REF( XTypeProvider ), + CPPU_TYPE_REF( XServiceInfo ), + CPPU_TYPE_REF( XContentProvider ), + CPPU_TYPE_REF( XParameterizedContentProvider ), + CPPU_TYPE_REF( XContentProviderSupplier ) ); + return collection.getTypes(); + } +} + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_NOFACTORY_IMPL_1( UcbContentProviderProxy, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UcbContentProviderProxy" ), + OUString::createFromAscii( + PROVIDER_PROXY_SERVICE_NAME ) ); + +//========================================================================= +// +// XContentProvider methods. +// +//========================================================================= + +// virtual +Reference< XContent > SAL_CALL UcbContentProviderProxy::queryContent( + const Reference< XContentIdentifier >& Identifier ) + throw( IllegalIdentifierException, + RuntimeException ) +{ + // Get original provider an forward the call... + + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + Reference< XContentProvider > xProvider = getContentProvider(); + if ( xProvider.is() ) + return xProvider->queryContent( Identifier ); + + return Reference< XContent >(); +} + +//========================================================================= +// virtual +sal_Int32 SAL_CALL UcbContentProviderProxy::compareContentIds( + const Reference< XContentIdentifier >& Id1, + const Reference< XContentIdentifier >& Id2 ) + throw( RuntimeException ) +{ + // Get original provider an forward the call... + + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + Reference< XContentProvider > xProvider = getContentProvider(); + if ( xProvider.is() ) + return xProvider->compareContentIds( Id1, Id2 ); + + // OSL_ENSURE( sal_False, + // "UcbContentProviderProxy::compareContentIds - No provider!" ); + + // @@@ What else? + return 0; +} + +//========================================================================= +// +// XParameterizedContentProvider methods. +// +//========================================================================= + +// virtual +Reference< XContentProvider > SAL_CALL +UcbContentProviderProxy::registerInstance( const OUString& Template, + const OUString& Arguments, + sal_Bool ReplaceExisting ) + throw( IllegalArgumentException, + RuntimeException ) +{ + // Just remember that this method was called ( and the params ). + + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( !m_bRegister ) + { +// m_xTargetProvider = 0; + m_aTemplate = Template; + m_aArguments = Arguments; + m_bReplace = ReplaceExisting; + + m_bRegister = sal_True; + } + return this; +} + +//========================================================================= +// virtual +Reference< XContentProvider > SAL_CALL +UcbContentProviderProxy::deregisterInstance( const OUString& Template, + const OUString& Arguments ) + throw( IllegalArgumentException, + RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + // registerInstance called at proxy and at original? + if ( m_bRegister && m_xTargetProvider.is() ) + { + m_bRegister = sal_False; + m_xTargetProvider = 0; + + Reference< XParameterizedContentProvider > + xParamProvider( m_xProvider, UNO_QUERY ); + if ( xParamProvider.is() ) + { + try + { + xParamProvider->deregisterInstance( Template, Arguments ); + } + catch ( IllegalIdentifierException const & ) + { + OSL_ENSURE( sal_False, + "UcbContentProviderProxy::deregisterInstance - " + "Caught IllegalIdentifierException!" ); + } + } + } + + return this; +} + +//========================================================================= +// +// XContentProviderSupplier methods. +// +//========================================================================= + +// virtual +Reference< XContentProvider > SAL_CALL +UcbContentProviderProxy::getContentProvider() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + if ( !m_xProvider.is() ) + { + try + { + m_xProvider + = Reference< XContentProvider >( + m_xSMgr->createInstance( m_aService ), UNO_QUERY ); + if(m_aArguments.compareToAscii("NoConfig") == 0) + { + Reference<XInitialization> xInit(m_xProvider,UNO_QUERY); + if(xInit.is()) { + Sequence<Any> aArgs(1); + aArgs[0] <<= m_aArguments; + xInit->initialize(aArgs); + } + } + } + catch ( RuntimeException const & ) + { + throw; + } + catch ( Exception const & ) + { + } + + // registerInstance called at proxy, but not yet at original? + if ( m_xProvider.is() && m_bRegister ) + { + Reference< XParameterizedContentProvider > + xParamProvider( m_xProvider, UNO_QUERY ); + if ( xParamProvider.is() ) + { + try + { + m_xTargetProvider + = xParamProvider->registerInstance( m_aTemplate, + m_aArguments, + m_bReplace ); + } + catch ( IllegalIdentifierException const & ) + { + OSL_ENSURE( sal_False, + "UcbContentProviderProxy::getContentProvider - " + "Caught IllegalIdentifierException!" ); + } + + OSL_ENSURE( m_xTargetProvider.is(), + "UcbContentProviderProxy::getContentProvider - " + "No provider!" ); + } + } + if ( !m_xTargetProvider.is() ) + m_xTargetProvider = m_xProvider; + } + + OSL_ENSURE( m_xProvider.is(), + "UcbContentProviderProxy::getContentProvider - No provider!" ); + return m_xTargetProvider; +} diff --git a/ucb/source/core/provprox.hxx b/ucb/source/core/provprox.hxx new file mode 100644 index 000000000000..cdc85251e96e --- /dev/null +++ b/ucb/source/core/provprox.hxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * 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 _PROVPROX_HXX +#define _PROVPROX_HXX + +#include <osl/mutex.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ucb/XContentProviderFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XParameterizedContentProvider.hpp> +#include <com/sun/star/ucb/XContentProviderSupplier.hpp> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> + +//========================================================================= + +#define PROVIDER_FACTORY_SERVICE_NAME \ + "com.sun.star.ucb.ContentProviderProxyFactory" +#define PROVIDER_PROXY_SERVICE_NAME \ + "com.sun.star.ucb.ContentProviderProxy" + +//============================================================================ +// +// class UcbContentProviderProxyFactory. +// +//============================================================================ + +class UcbContentProviderProxyFactory : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::ucb::XContentProviderFactory +{ + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > + m_xSMgr; + +public: + UcbContentProviderProxyFactory( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rxSMgr ); + virtual ~UcbContentProviderProxyFactory(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_DECL() + + // XContentProviderFactory + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentProvider > SAL_CALL + createContentProvider( const ::rtl::OUString& Service ) + throw( ::com::sun::star::uno::RuntimeException ); +}; + +//============================================================================ +// +// class UcbContentProviderProxy. +// +//============================================================================ + +class UcbContentProviderProxy : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::ucb::XContentProviderSupplier, + public com::sun::star::ucb::XContentProvider, + public com::sun::star::ucb::XParameterizedContentProvider +{ + ::osl::Mutex m_aMutex; + ::rtl::OUString m_aService; + ::rtl::OUString m_aTemplate; + ::rtl::OUString m_aArguments; + sal_Bool m_bReplace; + sal_Bool m_bRegister; + + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > + m_xSMgr; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > + m_xProvider; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > + m_xTargetProvider; + +public: + UcbContentProviderProxy( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const ::rtl::OUString& Service ); + virtual ~UcbContentProviderProxy(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_NOFACTORY_DECL() + + // XContentProviderSupplier + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentProvider > SAL_CALL + getContentProvider() + throw( ::com::sun::star::uno::RuntimeException ); + + // 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 ); + virtual sal_Int32 SAL_CALL + compareContentIds( const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Id1, + const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Id2 ) + throw( ::com::sun::star::uno::RuntimeException ); + + // XParameterizedContentProvider + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentProvider > SAL_CALL + registerInstance( const ::rtl::OUString& Template, + const ::rtl::OUString& Arguments, + sal_Bool ReplaceExisting ) + throw( ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentProvider > SAL_CALL + deregisterInstance( const ::rtl::OUString& Template, + const ::rtl::OUString& Arguments ) + throw( ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException ); +}; + +#endif /* !_PROVPROX_HXX */ diff --git a/ucb/source/core/ucb.cxx b/ucb/source/core/ucb.cxx new file mode 100644 index 000000000000..30f7e32f3828 --- /dev/null +++ b/ucb/source/core/ucb.cxx @@ -0,0 +1,959 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +#include <osl/diagnose.h> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentProviderSupplier.hpp> +#include <com/sun/star/ucb/XParameterizedContentProvider.hpp> +#include <com/sun/star/ucb/XContentProviderFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <ucbhelper/cancelcommandexecution.hxx> +#include "identify.hxx" +#include "ucbcmds.hxx" + +#include "ucb.hxx" + +// Definitions for ProviderMap_Impl (Solaris wouldn't find explicit template +// instantiations for these in another compilation unit...): +#ifndef _UCB_REGEXPMAP_TPT_ +#include <regexpmap.tpt> +#endif + +using namespace rtl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace ucb_impl; +using namespace com::sun::star; +using namespace ucbhelper; + + +#define CONFIG_CONTENTPROVIDERS_KEY \ + "/org.openoffice.ucb.Configuration/ContentProviders" + + +namespace { + +bool fillPlaceholders(rtl::OUString const & rInput, + uno::Sequence< uno::Any > const & rReplacements, + rtl::OUString * pOutput) +{ + sal_Unicode const * p = rInput.getStr(); + sal_Unicode const * pEnd = p + rInput.getLength(); + sal_Unicode const * pCopy = p; + rtl::OUStringBuffer aBuffer; + while (p != pEnd) + switch (*p++) + { + case '&': + if (pEnd - p >= 4 + && p[0] == 'a' && p[1] == 'm' && p[2] == 'p' + && p[3] == ';') + { + aBuffer.append(pCopy, p - 1 - pCopy); + aBuffer.append(sal_Unicode('&')); + p += 4; + pCopy = p; + } + else if (pEnd - p >= 3 + && p[0] == 'l' && p[1] == 't' && p[2] == ';') + { + aBuffer.append(pCopy, p - 1 - pCopy); + aBuffer.append(sal_Unicode('<')); + p += 3; + pCopy = p; + } + else if (pEnd - p >= 3 + && p[0] == 'g' && p[1] == 't' && p[2] == ';') + { + aBuffer.append(pCopy, p - 1 - pCopy); + aBuffer.append(sal_Unicode('>')); + p += 3; + pCopy = p; + } + break; + + case '<': + sal_Unicode const * q = p; + while (q != pEnd && *q != '>') + ++q; + if (q == pEnd) + break; + rtl::OUString aKey(p, q - p); + rtl::OUString aValue; + bool bFound = false; + for (sal_Int32 i = 2; i + 1 < rReplacements.getLength(); + i += 2) + { + rtl::OUString aReplaceKey; + if ((rReplacements[i] >>= aReplaceKey) + && aReplaceKey == aKey + && (rReplacements[i + 1] >>= aValue)) + { + bFound = true; + break; + } + } + if (!bFound) + return false; + aBuffer.append(pCopy, p - 1 - pCopy); + aBuffer.append(aValue); + p = q + 1; + pCopy = p; + break; + } + aBuffer.append(pCopy, pEnd - pCopy); + *pOutput = aBuffer.makeStringAndClear(); + return true; +} + +void makeAndAppendXMLName( + rtl::OUStringBuffer & rBuffer, const rtl::OUString & rIn ) +{ + 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( "&" ); + break; + + case '"': + rBuffer.appendAscii( """ ); + break; + + case '\'': + rBuffer.appendAscii( "'" ); + break; + + case '<': + rBuffer.appendAscii( "<" ); + break; + + case '>': + rBuffer.appendAscii( ">" ); + break; + + default: + rBuffer.append( c ); + break; + } + } +} + +bool createContentProviderData( + const rtl::OUString & rProvider, + const uno::Reference< container::XHierarchicalNameAccess >& rxHierNameAccess, + ContentProviderData & rInfo) +{ + // Obtain service name. + rtl::OUStringBuffer aKeyBuffer (rProvider); + aKeyBuffer.appendAscii( "/ServiceName" ); + + rtl::OUString aValue; + try + { + if ( !( rxHierNameAccess->getByHierarchicalName( + aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) + { + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - " + "Error getting item value!" ); + } + } + catch (container::NoSuchElementException &) + { + return false; + } + + rInfo.ServiceName = aValue; + + // Obtain URL Template. + aKeyBuffer.append(rProvider); + aKeyBuffer.appendAscii( "/URLTemplate" ); + + if ( !( rxHierNameAccess->getByHierarchicalName( + aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) + { + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - " + "Error getting item value!" ); + } + + rInfo.URLTemplate = aValue; + + // Obtain Arguments. + aKeyBuffer.append(rProvider); + aKeyBuffer.appendAscii( "/Arguments" ); + + if ( !( rxHierNameAccess->getByHierarchicalName( + aKeyBuffer.makeStringAndClear() ) >>= aValue ) ) + { + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - " + "Error getting item value!" ); + } + + rInfo.Arguments = aValue; + return true; +} + +} + +//========================================================================= +// +// UniversalContentBroker Implementation. +// +//========================================================================= + +UniversalContentBroker::UniversalContentBroker( + const Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr ) +: m_xSMgr( rXSMgr ), + m_pDisposeEventListeners( NULL ), + m_nInitCount( 0 ), //@@@ see initialize() method + m_nCommandId( 0 ) +{ + OSL_ENSURE( m_xSMgr.is(), + "UniversalContentBroker ctor: No service manager" ); +} + +//========================================================================= +// virtual +UniversalContentBroker::~UniversalContentBroker() +{ + delete m_pDisposeEventListeners; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_8( UniversalContentBroker, + XTypeProvider, + XComponent, + XServiceInfo, + XInitialization, + XContentProviderManager, + XContentProvider, + XContentIdentifierFactory, + XCommandProcessor ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_8( UniversalContentBroker, + XTypeProvider, + XComponent, + XServiceInfo, + XInitialization, + XContentProviderManager, + XContentProvider, + XContentIdentifierFactory, + XCommandProcessor ); + +//========================================================================= +// +// XComponent methods. +// +//========================================================================= + +// virtual +void SAL_CALL UniversalContentBroker::dispose() + throw( com::sun::star::uno::RuntimeException ) +{ + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = SAL_STATIC_CAST( XComponent*, this ); + m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + + if ( m_xNotifier.is() ) + m_xNotifier->removeChangesListener( this ); +} + +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::addEventListener( + const Reference< XEventListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ) +{ + if ( !m_pDisposeEventListeners ) + m_pDisposeEventListeners = new OInterfaceContainerHelper( m_aMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::removeEventListener( + const Reference< XEventListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ) +{ + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); + + // Note: Don't want to delete empty container here -> performance. +} + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_IMPL_1( UniversalContentBroker, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UniversalContentBroker" ), + OUString::createFromAscii( + UCB_SERVICE_NAME ) ); + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( UniversalContentBroker ); + +//========================================================================= +// +// XInitialization methods. +// +//========================================================================= + +// virtual +void SAL_CALL UniversalContentBroker::initialize( + const com::sun::star::uno::Sequence< Any >& aArguments ) + throw( com::sun::star::uno::Exception, + com::sun::star::uno::RuntimeException ) +{ + //@@@ At the moment, there's a problem when one (non-one-instance) factory + // 'wraps' another (one-instance) factory, causing this method to be + // called several times: + m_aArguments = aArguments; + + oslInterlockedCount nCount = osl_incrementInterlockedCount(&m_nInitCount); + if (nCount == 1) + configureUcb(); + else + osl_decrementInterlockedCount(&m_nInitCount); + // make the possibility of overflow less likely... +} + +//========================================================================= +// +// XContentProviderManager methods. +// +//========================================================================= + +// virtual +Reference< XContentProvider > SAL_CALL +UniversalContentBroker::registerContentProvider( + const Reference< XContentProvider >& Provider, + const OUString& Scheme, + sal_Bool ReplaceExisting ) + throw( DuplicateProviderException, com::sun::star::uno::RuntimeException ) +{ + osl::MutexGuard aGuard(m_aMutex); + + ProviderMap_Impl::iterator aIt; + try + { + aIt = m_aProviders.find(Scheme); + } + catch (IllegalArgumentException const &) + { + return 0; //@@@ + } + + Reference< XContentProvider > xPrevious; + if (aIt == m_aProviders.end()) + { + ProviderList_Impl aList; + aList.push_front(Provider); + try + { + m_aProviders.add(Scheme, aList, false); + } + catch (IllegalArgumentException const &) + { + return 0; //@@@ + } + } + else + { + if (!ReplaceExisting) + throw DuplicateProviderException(); + + ProviderList_Impl & rList = aIt->getValue(); + xPrevious = rList.front().getProvider(); + rList.push_front(Provider); + } + + return xPrevious; +} + +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::deregisterContentProvider( + const Reference< XContentProvider >& Provider, + const OUString& Scheme ) + throw( com::sun::star::uno::RuntimeException ) +{ + osl::MutexGuard aGuard(m_aMutex); + + ProviderMap_Impl::iterator aMapIt; + try + { + aMapIt = m_aProviders.find(Scheme); + } + catch (IllegalArgumentException const &) + { + return; //@@@ + } + + if (aMapIt != m_aProviders.end()) + { + ProviderList_Impl & rList = aMapIt->getValue(); + + ProviderList_Impl::iterator aListEnd(rList.end()); + for (ProviderList_Impl::iterator aListIt(rList.begin()); + aListIt != aListEnd; ++aListIt) + { + if ((*aListIt).getProvider() == Provider) + { + rList.erase(aListIt); + break; + } + } + + if (rList.empty()) + m_aProviders.erase(aMapIt); + } +} + +//========================================================================= +// virtual +com::sun::star::uno::Sequence< ContentProviderInfo > SAL_CALL + UniversalContentBroker::queryContentProviders() + throw( com::sun::star::uno::RuntimeException ) +{ + // Return a list with information about active(!) content providers. + + osl::MutexGuard aGuard(m_aMutex); + + com::sun::star::uno::Sequence< ContentProviderInfo > aSeq( + m_aProviders.size() ); + ContentProviderInfo* pInfo = aSeq.getArray(); + + ProviderMap_Impl::const_iterator end = m_aProviders.end(); + for (ProviderMap_Impl::const_iterator it(m_aProviders.begin()); it != end; + ++it) + { + // Note: Active provider is always the first list element. + pInfo->ContentProvider = it->getValue().front().getProvider(); + pInfo->Scheme = it->getRegexp(); + ++pInfo; + } + + return aSeq; +} + +//========================================================================= +// virtual +Reference< XContentProvider > SAL_CALL + UniversalContentBroker::queryContentProvider( const OUString& + Identifier ) + throw( com::sun::star::uno::RuntimeException ) +{ + return queryContentProvider( Identifier, sal_False ); +} + +//========================================================================= +// +// XContentProvider methods. +// +//========================================================================= + +// virtual +Reference< XContent > SAL_CALL UniversalContentBroker::queryContent( + const Reference< XContentIdentifier >& Identifier ) + throw( IllegalIdentifierException, com::sun::star::uno::RuntimeException ) +{ + ////////////////////////////////////////////////////////////////////// + // Let the content provider for the scheme given with the content + // identifier create the XContent instance. + ////////////////////////////////////////////////////////////////////// + + if ( !Identifier.is() ) + return Reference< XContent >(); + + Reference< XContentProvider > xProv = + queryContentProvider( Identifier->getContentIdentifier(), sal_True ); + if ( xProv.is() ) + return xProv->queryContent( Identifier ); + + return Reference< XContent >(); +} + +//========================================================================= +// virtual +sal_Int32 SAL_CALL UniversalContentBroker::compareContentIds( + const Reference< XContentIdentifier >& Id1, + const Reference< XContentIdentifier >& Id2 ) + throw( com::sun::star::uno::RuntimeException ) +{ + OUString aURI1( Id1->getContentIdentifier() ); + OUString aURI2( Id2->getContentIdentifier() ); + + Reference< XContentProvider > xProv1 + = queryContentProvider( aURI1, sal_True ); + Reference< XContentProvider > xProv2 + = queryContentProvider( aURI2, sal_True ); + + // When both identifiers belong to the same provider, let that provider + // compare them; otherwise, simply compare the URI strings (which must + // be different): + if ( xProv1.is() && ( xProv1 == xProv2 ) ) + return xProv1->compareContentIds( Id1, Id2 ); + else + return aURI1.compareTo( aURI2 ); +} + +//========================================================================= +// +// XContentIdentifierFactory methods. +// +//========================================================================= + +// virtual +Reference< XContentIdentifier > SAL_CALL + UniversalContentBroker::createContentIdentifier( + const OUString& ContentId ) + throw( com::sun::star::uno::RuntimeException ) +{ + ////////////////////////////////////////////////////////////////////// + // Let the content provider for the scheme given with content + // identifier create the XContentIdentifier instance, if he supports + // the XContentIdentifierFactory interface. Otherwise create standard + // implementation object for XContentIdentifier. + ////////////////////////////////////////////////////////////////////// + + Reference< XContentIdentifier > xIdentifier; + + Reference< XContentProvider > xProv + = queryContentProvider( ContentId, sal_True ); + if ( xProv.is() ) + { + Reference< XContentIdentifierFactory > xFac( xProv, UNO_QUERY ); + if ( xFac.is() ) + xIdentifier = xFac->createContentIdentifier( ContentId ); + } + + if ( !xIdentifier.is() ) + xIdentifier = new ContentIdentifier( m_xSMgr, ContentId ); + + return xIdentifier; +} + +//========================================================================= +// +// XCommandProcessor methods. +// +//========================================================================= + +// virtual +sal_Int32 SAL_CALL UniversalContentBroker::createCommandIdentifier() + throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + // Just increase counter on every call to generate an identifier. + return ++m_nCommandId; +} + +//========================================================================= +// virtual +Any SAL_CALL UniversalContentBroker::execute( + const Command& aCommand, + sal_Int32, + const Reference< XCommandEnvironment >& Environment ) + throw( Exception, CommandAbortedException, RuntimeException ) +{ + Any aRet; + + ////////////////////////////////////////////////////////////////////// + // Note: Don't forget to adapt ucb_commands::CommandProcessorInfo + // ctor in ucbcmds.cxx when adding new commands! + ////////////////////////////////////////////////////////////////////// + + if ( ( aCommand.Handle == GETCOMMANDINFO_HANDLE ) || + aCommand.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( GETCOMMANDINFO_NAME ) ) ) + { + ////////////////////////////////////////////////////////////////// + // getCommandInfo + ////////////////////////////////////////////////////////////////// + + aRet <<= getCommandInfo(); + } + else if ( ( aCommand.Handle == GLOBALTRANSFER_HANDLE ) || + aCommand.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM(GLOBALTRANSFER_NAME ) ) ) + { + ////////////////////////////////////////////////////////////////// + // globalTransfer + ////////////////////////////////////////////////////////////////// + + GlobalTransferCommandArgument aTransferArg; + if ( !( aCommand.Argument >>= aTransferArg ) ) + { + ucbhelper::cancelCommandExecution( + makeAny( IllegalArgumentException( + rtl::OUString::createFromAscii( + "Wrong argument type!" ), + static_cast< cppu::OWeakObject * >( this ), + -1 ) ), + Environment ); + // Unreachable + } + + globalTransfer( aTransferArg, Environment ); + } + else + { + ////////////////////////////////////////////////////////////////// + // Unknown command + ////////////////////////////////////////////////////////////////// + + ucbhelper::cancelCommandExecution( + makeAny( UnsupportedCommandException( + rtl::OUString(), + static_cast< cppu::OWeakObject * >( this ) ) ), + Environment ); + // Unreachable + } + + return aRet; +} + +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::abort( sal_Int32 ) + throw( RuntimeException ) +{ + // @@@ Not implemeted ( yet). +} + +//========================================================================= +// +// XChangesListener methods +// +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::changesOccurred( const util::ChangesEvent& Event ) + throw( uno::RuntimeException ) +{ + sal_Int32 nCount = Event.Changes.getLength(); + if ( nCount ) + { + uno::Reference< container::XHierarchicalNameAccess > xHierNameAccess; + Event.Base >>= xHierNameAccess; + + OSL_ASSERT( xHierNameAccess.is() ); + + const util::ElementChange* pElementChanges + = Event.Changes.getConstArray(); + + ContentProviderDataList aData; + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const util::ElementChange& rElem = pElementChanges[ n ]; + rtl::OUString aKey; + rElem.Accessor >>= aKey; + + ContentProviderData aInfo; + + // Removal of UCPs from the configuration leads to changesOccurred + // notifications, too, but it is hard to tell for a given + // ElementChange whether it is an addition or a removal, so as a + // heuristic consider as removals those that cause a + // NoSuchElementException in createContentProviderData. + // + // For now, removal of UCPs from the configuration is simply ignored + // (and not reflected in the UCB's data structures): + if (createContentProviderData(aKey, xHierNameAccess, aInfo)) + { + aData.push_back(aInfo); + } + } + + prepareAndRegister(aData); + } +} + +//========================================================================= +// +// XEventListener methods +// +//========================================================================= +// virtual +void SAL_CALL UniversalContentBroker::disposing(const lang::EventObject&) + throw( uno::RuntimeException ) +{ + if ( m_xNotifier.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( m_xNotifier.is() ) + m_xNotifier.clear(); + } +} + +//========================================================================= +// +// Non-interface methods +// +//========================================================================= + +Reference< XContentProvider > UniversalContentBroker::queryContentProvider( + const OUString& Identifier, + sal_Bool bResolved ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + ProviderList_Impl const * pList = m_aProviders.map( Identifier ); + return pList ? bResolved ? pList->front().getResolvedProvider() + : pList->front().getProvider() + : Reference< XContentProvider >(); +} + +bool UniversalContentBroker::configureUcb() + throw (uno::RuntimeException) +{ + rtl::OUString aKey1; + rtl::OUString aKey2; + if (m_aArguments.getLength() < 2 + || !(m_aArguments[0] >>= aKey1) || !(m_aArguments[1] >>= aKey2)) + { + OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): Bad arguments"); + return false; + } + + ContentProviderDataList aData; + if (!getContentProviderData(aKey1, aKey2, aData)) + { + OSL_ENSURE(false, "UniversalContentBroker::configureUcb(): No configuration"); + return false; + } + + prepareAndRegister(aData); + + return true; +} + +void UniversalContentBroker::prepareAndRegister( + const ContentProviderDataList& rData) +{ + ContentProviderDataList::const_iterator aEnd(rData.end()); + for (ContentProviderDataList::const_iterator aIt(rData.begin()); + aIt != aEnd; ++aIt) + { + rtl::OUString aProviderArguments; + if (fillPlaceholders(aIt->Arguments, + m_aArguments, + &aProviderArguments)) + { + registerAtUcb(this, + m_xSMgr, + aIt->ServiceName, + aProviderArguments, + aIt->URLTemplate, + 0); + + } + else + OSL_ENSURE(false, + "UniversalContentBroker::prepareAndRegister(): Bad argument placeholders"); + } +} + +//========================================================================= +bool UniversalContentBroker::getContentProviderData( + const rtl::OUString & rKey1, + const rtl::OUString & rKey2, + ContentProviderDataList & rListToFill ) +{ + if ( !m_xSMgr.is() || !rKey1.getLength() || !rKey2.getLength() ) + { + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - Invalid argument!" ); + return false; + } + + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProv( + m_xSMgr->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ) ), + uno::UNO_QUERY_THROW ); + + rtl::OUStringBuffer aFullPath; + aFullPath.appendAscii( CONFIG_CONTENTPROVIDERS_KEY "/['" ); + makeAndAppendXMLName( aFullPath, rKey1 ); + aFullPath.appendAscii( "']/SecondaryKeys/['" ); + makeAndAppendXMLName( aFullPath, rKey2 ); + aFullPath.appendAscii( "']/ProviderData" ); + + uno::Sequence< uno::Any > aArguments( 1 ); + beans::PropertyValue aProperty; + aProperty.Name + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + aProperty.Value <<= aFullPath.makeStringAndClear(); + aArguments[ 0 ] <<= aProperty; + + uno::Reference< uno::XInterface > xInterface( + xConfigProv->createInstanceWithArguments( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationAccess" ) ), + aArguments ) ); + + if ( !m_xNotifier.is() ) + { + m_xNotifier = uno::Reference< util::XChangesNotifier >( + xInterface, uno::UNO_QUERY_THROW ); + + m_xNotifier->addChangesListener( this ); + } + + uno::Reference< container::XNameAccess > xNameAccess( + xInterface, uno::UNO_QUERY_THROW ); + + uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames(); + const rtl::OUString* pElems = aElems.getConstArray(); + sal_Int32 nCount = aElems.getLength(); + + if ( nCount > 0 ) + { + uno::Reference< container::XHierarchicalNameAccess > + xHierNameAccess( xInterface, uno::UNO_QUERY_THROW ); + + // Iterate over children. + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + + try + { + + ContentProviderData aInfo; + + rtl::OUStringBuffer aElemBuffer; + aElemBuffer.appendAscii( "['" ); + makeAndAppendXMLName( aElemBuffer, pElems[ n ] ); + aElemBuffer.appendAscii( "']" ); + + OSL_VERIFY( + createContentProviderData( + aElemBuffer.makeStringAndClear(), xHierNameAccess, + aInfo)); + + rListToFill.push_back( aInfo ); + } + catch ( container::NoSuchElementException& ) + { + // getByHierarchicalName + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - " + "caught NoSuchElementException!" ); + } + } + } + } + catch ( uno::RuntimeException& ) + { + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - caught RuntimeException!" ); + return false; + } + catch ( uno::Exception& ) + { + // createInstance, createInstanceWithArguments + + OSL_ENSURE( false, + "UniversalContentBroker::getContentProviderData - caught Exception!" ); + return false; + } + + return true; +} + +//========================================================================= +// +// ProviderListEntry_Impl implementation. +// +//========================================================================= + +Reference< XContentProvider > ProviderListEntry_Impl::resolveProvider() const +{ + if ( !m_xResolvedProvider.is() ) + { + Reference< XContentProviderSupplier > xSupplier( + m_xProvider, UNO_QUERY ); + if ( xSupplier.is() ) + m_xResolvedProvider = xSupplier->getContentProvider(); + + if ( !m_xResolvedProvider.is() ) + m_xResolvedProvider = m_xProvider; + } + + return m_xResolvedProvider; +} diff --git a/ucb/source/core/ucb.hxx b/ucb/source/core/ucb.hxx new file mode 100644 index 000000000000..d2f6e4e4c41e --- /dev/null +++ b/ucb/source/core/ucb.hxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * 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 _UCB_HXX +#define _UCB_HXX + +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifierFactory.hpp> +#include <com/sun/star/ucb/XContentProviderManager.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/container/XContainer.hpp> + +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/weak.hxx> +#include <osl/mutex.hxx> +#include <osl/interlck.h> +#include <ucbhelper/macros.hxx> +#include "providermap.hxx" +#include <ucbhelper/registerucb.hxx> + +#include <vector> +//========================================================================= + +#define UCB_SERVICE_NAME "com.sun.star.ucb.UniversalContentBroker" + +//========================================================================= + +namespace cppu { class OInterfaceContainerHelper; } + +namespace com { namespace sun { namespace star { namespace ucb { + class XCommandInfo; + struct GlobalTransferCommandArgument; +} } } } + +class UniversalContentBroker : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XComponent, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::lang::XInitialization, + public com::sun::star::ucb::XContentProviderManager, + public com::sun::star::ucb::XContentProvider, + public com::sun::star::ucb::XContentIdentifierFactory, + public com::sun::star::ucb::XCommandProcessor, + public com::sun::star::util::XChangesListener +{ +public: + UniversalContentBroker( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rXSMgr ); + virtual ~UniversalContentBroker(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_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 >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< + com::sun::star::lang::XEventListener >& Listener ) + throw( 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 ); + + // XContentProviderManager + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > SAL_CALL + registerContentProvider( const com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider >& + Provider, + const rtl::OUString& Scheme, + sal_Bool ReplaceExisting ) + throw( com::sun::star::ucb::DuplicateProviderException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + deregisterContentProvider( const com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider >& + Provider, + const rtl::OUString& Scheme ) + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< + com::sun::star::ucb::ContentProviderInfo > SAL_CALL + queryContentProviders() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProvider > SAL_CALL + queryContentProvider( const rtl::OUString& Identifier ) + throw( com::sun::star::uno::RuntimeException ); + + // 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 ); + virtual sal_Int32 SAL_CALL + compareContentIds( const com::sun::star::uno::Reference< + com::sun::star::ucb::XContentIdentifier >& Id1, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XContentIdentifier >& Id2 ) + throw( com::sun::star::uno::RuntimeException ); + + // XContentIdentifierFactory + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XContentIdentifier > SAL_CALL + createContentIdentifier( const rtl::OUString& ContentId ) + throw( com::sun::star::uno::RuntimeException ); + + // XCommandProcessor + virtual sal_Int32 SAL_CALL + createCommandIdentifier() + throw( com::sun::star::uno::RuntimeException ); + 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 ); + + // XChangesListener + virtual void SAL_CALL changesOccurred( const com::sun::star::util::ChangesEvent& Event ) + throw( com::sun::star::uno::RuntimeException ); + + // XEventListener ( base of XChangesLisetenr ) + virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& Source ) + throw( com::sun::star::uno::RuntimeException ); + +private: + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > + queryContentProvider( const rtl::OUString& Identifier, + sal_Bool bResolved ); + + com::sun::star::uno::Reference< com::sun::star::ucb::XCommandInfo > + getCommandInfo(); + + void + globalTransfer( + const com::sun::star::ucb::GlobalTransferCommandArgument & rArg, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& xEnv ) + throw( com::sun::star::uno::Exception ); + + + bool configureUcb() + throw ( com::sun::star::uno::RuntimeException); + + bool getContentProviderData( + const rtl::OUString & rKey1, + const rtl::OUString & rKey2, + ucbhelper::ContentProviderDataList & rListToFill); + + void prepareAndRegister( const ucbhelper::ContentProviderDataList& rData); + + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > m_xSMgr; + + com::sun::star::uno::Reference< + com::sun::star::util::XChangesNotifier > m_xNotifier; + + com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_aArguments; + ProviderMap_Impl m_aProviders; + osl::Mutex m_aMutex; + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + oslInterlockedCount m_nInitCount; //@@@ see initialize() method + sal_Int32 m_nCommandId; +}; + +#endif /* !_UCB_HXX */ diff --git a/ucb/source/core/ucb.xml b/ucb/source/core/ucb.xml new file mode 100644 index 000000000000..1473c035ba83 --- /dev/null +++ b/ucb/source/core/ucb.xml @@ -0,0 +1,172 @@ +<?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> + ucb + </module-name> + + <component-description> + <author> + Kai Sommerfeld + </author> + <name> + com.sun.star.comp.ucb.UniversalContentBroker + </name> + <description> + This component provides access to a set of Contents via Content Providers. + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.UniversalContentBroker + </supported-service> + + <service-dependency> + com.sun.star.io.Pipe + </service-dependency> + </component-description> + <component-description> + <author> + Kai Sommerfeld + </author> + <name> + com.sun.star.comp.ucb.UcbStore + </name> + <description> + This component is a factory for components managing persistent data. + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.Store + </supported-service> + + <service-dependency> + com.sun.star.configuration.ConfigurationProvider + </service-dependency> + <service-dependency> + com.sun.star.configuration.ConfigurationAccess + </service-dependency> + <service-dependency> + com.sun.star.configuration.ConfigurationUpdateAccess + </service-dependency> + </component-description> + <component-description> + <author> + Kai Sommerfeld + </author> + <name> + com.sun.star.comp.ucb.UcbPropertiesManager + </name> + <description> + This component provides access to the meta data of the properties + known to the UCB. + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.PropertiesManager + </supported-service> + </component-description> + <component-description> + <author> + Kai Sommerfeld + </author> + <name> + com.sun.star.comp.ucb.UcbContentProviderProxyFactory + </name> + <description> + This component is a factory for proxy objects for Content Providers. + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.ContentProviderProxyFactory + </supported-service> + </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> ucbhelper1$(COM) </runtime-module-dependency> + + <type> com.sun.star.beans.PropertyAttribute </type> + <type> com.sun.star.beans.PropertySetInfoChange </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.XHierarchicalNameAccess </type> + <type> com.sun.star.container.XNamed </type> + <type> com.sun.star.container.XNameAccess </type> + <type> com.sun.star.container.XNameContainer </type> + <type> com.sun.star.io.XActiveDataSink </type> + <type> com.sun.star.io.XOutputStream </type> + <type> com.sun.star.io.XSeekable </type> + <type> com.sun.star.lang.IllegalArgumentException </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.XRow </type> + <type> com.sun.star.ucb.ContentInfoAttribute </type> + <type> com.sun.star.ucb.CrossReference </type> + <type> com.sun.star.ucb.DocumentHeaderField </type> + <type> com.sun.star.ucb.GlobalTransferCommandArgument </type> + <type> com.sun.star.ucb.InsertCommandArgument </type> + <type> com.sun.star.ucb.InteractiveBadTransferURLException </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.RecipientInfo </type> + <type> com.sun.star.ucb.RuleSet </type> + <type> com.sun.star.ucb.SendInfo </type> + <type> com.sun.star.ucb.SendMediaTypes </type> + <type> com.sun.star.ucb.TransferInfo </type> + <type> com.sun.star.ucb.UnsupportedNameClashException </type> + <type> com.sun.star.ucb.XCommandInfo </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.XContentIdentifier </type> + <type> com.sun.star.ucb.XContentIdentifierFactory </type> + <type> com.sun.star.ucb.XContentProvider </type> + <type> com.sun.star.ucb.XContentProviderFactory </type> + <type> com.sun.star.ucb.XContentProviderManager </type> + <type> com.sun.star.ucb.XContentProviderSupplier </type> + <type> com.sun.star.ucb.XDataContainer </type> + <type> com.sun.star.ucb.XDynamicResultSet </type> + <type> com.sun.star.ucb.XParameterizedContentProvider </type> + <type> com.sun.star.ucb.XPropertySetRegistryFactory </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.util.DateTime </type> + <type> com.sun.star.util.XChangesBatch </type> +</module-description> diff --git a/ucb/source/core/ucb1.component b/ucb/source/core/ucb1.component new file mode 100644 index 000000000000..e9d408822cc9 --- /dev/null +++ b/ucb/source/core/ucb1.component @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.ucb.CommandEnvironment"> + <service name="com.sun.star.ucb.CommandEnvironment"/> + </implementation> + <implementation name="com.sun.star.comp.ucb.UcbContentProviderProxyFactory"> + <service name="com.sun.star.ucb.ContentProviderProxyFactory"/> + </implementation> + <implementation name="com.sun.star.comp.ucb.UcbPropertiesManager"> + <service name="com.sun.star.ucb.PropertiesManager"/> + </implementation> + <implementation name="com.sun.star.comp.ucb.UcbStore"> + <service name="com.sun.star.ucb.Store"/> + </implementation> + <implementation name="com.sun.star.comp.ucb.UniversalContentBroker"> + <service name="com.sun.star.ucb.UniversalContentBroker"/> + </implementation> +</component> diff --git a/ucb/source/core/ucbcmds.cxx b/ucb/source/core/ucbcmds.cxx new file mode 100644 index 000000000000..fd3f0f73c772 --- /dev/null +++ b/ucb/source/core/ucbcmds.cxx @@ -0,0 +1,2090 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +#include <osl/diagnose.h> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/ucb/CommandEnvironment.hpp> +#include <com/sun/star/ucb/CommandFailedException.hpp> +#include <com/sun/star/ucb/ContentInfoAttribute.hpp> +#include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> +#include <com/sun/star/ucb/NameClash.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/TransferInfo.hpp> +#include <com/sun/star/ucb/UnsupportedNameClashException.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/XContentCreator.hpp> +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <ucbhelper/cancelcommandexecution.hxx> +#include <ucbhelper/simplenameclashresolverequest.hxx> +#include "ucbcmds.hxx" +#include "ucb.hxx" + +using namespace com::sun::star; + +namespace +{ + +//========================================================================= +// +// struct TransferCommandContext. +// +//========================================================================= + +struct TransferCommandContext +{ + uno::Reference< lang::XMultiServiceFactory > xSMgr; + uno::Reference< ucb::XCommandProcessor > xProcessor; + uno::Reference< ucb::XCommandEnvironment > xEnv; + uno::Reference< ucb::XCommandEnvironment > xOrigEnv; + ucb::GlobalTransferCommandArgument aArg; + + TransferCommandContext( + const uno::Reference< lang::XMultiServiceFactory > & rxSMgr, + const uno::Reference< ucb::XCommandProcessor > & rxProcessor, + const uno::Reference< ucb::XCommandEnvironment > & rxEnv, + const uno::Reference< ucb::XCommandEnvironment > & rxOrigEnv, + const ucb::GlobalTransferCommandArgument & rArg ) + : xSMgr( rxSMgr ), xProcessor( rxProcessor ), xEnv( rxEnv ), + xOrigEnv( rxOrigEnv ), aArg( rArg ) {} +}; + +//========================================================================= +// +// class InteractionHandlerProxy. +// +//========================================================================= + +class InteractionHandlerProxy : + public cppu::WeakImplHelper1< task::XInteractionHandler > +{ + uno::Reference< task::XInteractionHandler > m_xOrig; + +public: + InteractionHandlerProxy( + const uno::Reference< task::XInteractionHandler > & xOrig ) + : m_xOrig( xOrig ) {} + + // XInteractionHandler methods. + virtual void SAL_CALL handle( + const uno::Reference< task::XInteractionRequest >& Request ) + throw ( uno::RuntimeException ); +}; + +//========================================================================= +// virtual +void SAL_CALL InteractionHandlerProxy::handle( + const uno::Reference< task::XInteractionRequest >& Request ) + throw ( uno::RuntimeException ) +{ + if ( !m_xOrig.is() ) + return; + + // Filter unwanted requests by just not handling them. + uno::Any aRequest = Request->getRequest(); + + // "transfer" + ucb::InteractiveBadTransferURLException aBadTransferURLEx; + if ( aRequest >>= aBadTransferURLEx ) + { + return; + } + else + { + // "transfer" + ucb::UnsupportedNameClashException aUnsupportedNameClashEx; + if ( aRequest >>= aUnsupportedNameClashEx ) + { + if ( aUnsupportedNameClashEx.NameClash + != ucb::NameClash::ERROR ) + return; + } + else + { + // "insert" + ucb::NameClashException aNameClashEx; + if ( aRequest >>= aNameClashEx ) + { + return; + } + else + { + // "transfer" + ucb::UnsupportedCommandException aUnsupportedCommandEx; + if ( aRequest >>= aUnsupportedCommandEx ) + { + return; + } + } + } + } + + // not filtered; let the original handler do the work. + m_xOrig->handle( Request ); +} + +//========================================================================= +// +// class ActiveDataSink. +// +//========================================================================= + +class ActiveDataSink : public cppu::WeakImplHelper1< io::XActiveDataSink > +{ + uno::Reference< io::XInputStream > m_xStream; + +public: + // XActiveDataSink methods. + virtual void SAL_CALL setInputStream( + const uno::Reference< io::XInputStream >& aStream ) + throw( uno::RuntimeException ); + virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream() + throw( uno::RuntimeException ); +}; + +//========================================================================= +// virtual +void SAL_CALL ActiveDataSink::setInputStream( + const uno::Reference< io::XInputStream >& aStream ) + throw( uno::RuntimeException ) +{ + m_xStream = aStream; +} + +//========================================================================= +// virtual +uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream() + throw( uno::RuntimeException ) +{ + return m_xStream; +} + +//========================================================================= +// +// class CommandProcessorInfo. +// +//========================================================================= + +class CommandProcessorInfo : + public cppu::WeakImplHelper1< ucb::XCommandInfo > +{ + uno::Sequence< ucb::CommandInfo > * m_pInfo; + +public: + CommandProcessorInfo(); + virtual ~CommandProcessorInfo(); + + // XCommandInfo methods + virtual uno::Sequence< ucb::CommandInfo > SAL_CALL getCommands() + throw( uno::RuntimeException ); + virtual ucb::CommandInfo SAL_CALL + getCommandInfoByName( const rtl::OUString& Name ) + throw( ucb::UnsupportedCommandException, uno::RuntimeException ); + virtual ucb::CommandInfo SAL_CALL + getCommandInfoByHandle( sal_Int32 Handle ) + throw( ucb::UnsupportedCommandException, uno::RuntimeException ); + virtual sal_Bool SAL_CALL hasCommandByName( const rtl::OUString& Name ) + throw( uno::RuntimeException ); + virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle ) + throw( uno::RuntimeException ); +}; + +//========================================================================= +CommandProcessorInfo::CommandProcessorInfo() +{ + m_pInfo = new uno::Sequence< ucb::CommandInfo >( 2 ); + + (*m_pInfo)[ 0 ] + = ucb::CommandInfo( + rtl::OUString::createFromAscii( GETCOMMANDINFO_NAME ), // Name + GETCOMMANDINFO_HANDLE, // Handle + getCppuVoidType() ); // ArgType + (*m_pInfo)[ 1 ] + = ucb::CommandInfo( + rtl::OUString::createFromAscii( GLOBALTRANSFER_NAME ), // Name + GLOBALTRANSFER_HANDLE, // Handle + getCppuType( + static_cast< + ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType +} + +//========================================================================= +// virtual +CommandProcessorInfo::~CommandProcessorInfo() +{ + delete m_pInfo; +} + +//========================================================================= +// virtual +uno::Sequence< ucb::CommandInfo > SAL_CALL +CommandProcessorInfo::getCommands() + throw( uno::RuntimeException ) +{ + return uno::Sequence< ucb::CommandInfo >( *m_pInfo ); +} + +//========================================================================= +// virtual +ucb::CommandInfo SAL_CALL +CommandProcessorInfo::getCommandInfoByName( const rtl::OUString& Name ) + throw( ucb::UnsupportedCommandException, uno::RuntimeException ) +{ + for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) + { + if ( (*m_pInfo)[ n ].Name == Name ) + return ucb::CommandInfo( (*m_pInfo)[ n ] ); + } + + throw ucb::UnsupportedCommandException(); +} + +//========================================================================= +// virtual +ucb::CommandInfo SAL_CALL +CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle ) + throw( ucb::UnsupportedCommandException, uno::RuntimeException ) +{ + for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) + { + if ( (*m_pInfo)[ n ].Handle == Handle ) + return ucb::CommandInfo( (*m_pInfo)[ n ] ); + } + + throw ucb::UnsupportedCommandException(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName( + const rtl::OUString& Name ) + throw( uno::RuntimeException ) +{ + for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) + { + if ( (*m_pInfo)[ n ].Name == Name ) + return sal_True; + } + + return sal_False; +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle ) + throw( uno::RuntimeException ) +{ + for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) + { + if ( (*m_pInfo)[ n ].Handle == Handle ) + return sal_True; + } + + return sal_False; +} + +//========================================================================= +//========================================================================= +//========================================================================= + +rtl::OUString createDesiredName( + const rtl::OUString & rSourceURL, const rtl::OUString & rNewTitle ) +{ + rtl::OUString aName( rNewTitle ); + if ( aName.getLength() == 0 ) + { + // calculate name using source URL + + // @@@ It's not guaranteed that slashes contained in the URL are + // actually path separators. This depends on the fact whether the + // URL is hierarchical. Only then the slashes are path separators. + // Therefore this algorithm is not guaranteed to work! But, ATM + // I don't know a better solution. It would have been better to + // have a member for the clashing name in + // UnsupportedNameClashException... + + sal_Int32 nLastSlash = rSourceURL.lastIndexOf( '/' ); + bool bTrailingSlash = false; + if ( nLastSlash == rSourceURL.getLength() - 1 ) + { + nLastSlash = rSourceURL.lastIndexOf( '/', nLastSlash ); + bTrailingSlash = true; + } + + if ( nLastSlash != -1 ) + { + if ( bTrailingSlash ) + aName = rSourceURL.copy( + nLastSlash + 1, + rSourceURL.getLength() - nLastSlash - 2 ); + else + aName = rSourceURL.copy( nLastSlash + 1 ); + } + else + { + aName = rSourceURL; + } + + // query, fragment present? + sal_Int32 nPos = aName.indexOf( '?' ); + if ( nPos == -1 ) + nPos = aName.indexOf( '#' ); + + if ( nPos != -1 ) + aName = aName.copy( 0, nPos ); + } + return rtl::OUString( aName ); +} + +rtl::OUString createDesiredName( + const ucb::GlobalTransferCommandArgument & rArg ) +{ + return createDesiredName( rArg.SourceURL, rArg.NewTitle ); +} + +rtl::OUString createDesiredName( + const ucb::TransferInfo & rArg ) +{ + return createDesiredName( rArg.SourceURL, rArg.NewTitle ); +} + +//========================================================================= +enum NameClashContinuation { NOT_HANDLED, ABORT, OVERWRITE, NEW_NAME, UNKNOWN }; + +NameClashContinuation interactiveNameClashResolve( + const uno::Reference< ucb::XCommandEnvironment > & xEnv, + const rtl::OUString & rTargetURL, + const rtl::OUString & rClashingName, + /* [out] */ uno::Any & rException, + /* [out] */ rtl::OUString & rNewName ) +{ + rtl::Reference< ucbhelper::SimpleNameClashResolveRequest > xRequest( + new ucbhelper::SimpleNameClashResolveRequest( + rTargetURL, // target folder URL + rClashingName, // clashing name + rtl::OUString(), // no proposal for new name + sal_True /* bSupportsOverwriteData */ ) ); + + rException = xRequest->getRequest(); + if ( xEnv.is() ) + { + uno::Reference< task::XInteractionHandler > xIH + = xEnv->getInteractionHandler(); + if ( xIH.is() ) + { + + xIH->handle( xRequest.get() ); + + rtl::Reference< ucbhelper::InteractionContinuation > + xSelection( xRequest->getSelection() ); + + if ( xSelection.is() ) + { + // Handler handled the request. + uno::Reference< task::XInteractionAbort > xAbort( + xSelection.get(), uno::UNO_QUERY ); + if ( xAbort.is() ) + { + // Abort. + return ABORT; + } + else + { + uno::Reference< + ucb::XInteractionReplaceExistingData > + xReplace( + xSelection.get(), uno::UNO_QUERY ); + if ( xReplace.is() ) + { + // Try again: Replace existing data. + return OVERWRITE; + } + else + { + uno::Reference< + ucb::XInteractionSupplyName > + xSupplyName( + xSelection.get(), uno::UNO_QUERY ); + if ( xSupplyName.is() ) + { + // Try again: Use new name. + rNewName = xRequest->getNewName(); + return NEW_NAME; + } + else + { + OSL_ENSURE( sal_False, + "Unknown interaction continuation!" ); + return UNKNOWN; + } + } + } + } + } + } + return NOT_HANDLED; +} + +//========================================================================= +bool setTitle( + const uno::Reference< ucb::XCommandProcessor > & xCommandProcessor, + const uno::Reference< ucb::XCommandEnvironment > & xEnv, + const rtl::OUString & rNewTitle ) + throw( uno::RuntimeException ) +{ + try + { + uno::Sequence< beans::PropertyValue > aPropValues( 1 ); + aPropValues[ 0 ].Name + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); + aPropValues[ 0 ].Handle = -1; + aPropValues[ 0 ].Value = uno::makeAny( rNewTitle ); + + ucb::Command aSetPropsCommand( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ), + -1, + uno::makeAny( aPropValues ) ); + + uno::Any aResult + = xCommandProcessor->execute( aSetPropsCommand, 0, xEnv ); + + uno::Sequence< uno::Any > aErrors; + aResult >>= aErrors; + + OSL_ENSURE( aErrors.getLength() == 1, + "getPropertyValues return value invalid!" ); + + if ( aErrors[ 0 ].hasValue() ) + { + // error occured. + OSL_ENSURE( sal_False, "error setting Title property!" ); + return false; + } + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + return false; + } + + return true; +} + +//========================================================================= +uno::Reference< ucb::XContent > createNew( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XContent > & xTarget, + sal_Bool bSourceIsFolder, + sal_Bool bSourceIsDocument, + sal_Bool bSourceIsLink ) + throw( uno::Exception ) +{ + ////////////////////////////////////////////////////////////////////// + // + // (1) Obtain creatable types from target. + // + ////////////////////////////////////////////////////////////////////// + + // First, try it using "CreatabeleContentsInfo" property and + // "createNewContent" command -> the "new" way. + + uno::Reference< ucb::XCommandProcessor > xCommandProcessorT( + xTarget, uno::UNO_QUERY ); + if ( !xCommandProcessorT.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Folder")), + -1, + uno::makeAny(rContext.aArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_CREATE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( "Target is no XCommandProcessor!" ), + rContext.xProcessor ); + // Unreachable + } + + uno::Sequence< beans::Property > aPropsToObtain( 1 ); + aPropsToObtain[ 0 ].Name + = rtl::OUString::createFromAscii( "CreatableContentsInfo" ); + aPropsToObtain[ 0 ].Handle + = -1; + + ucb::Command aGetPropsCommand( + rtl::OUString::createFromAscii( "getPropertyValues" ), + -1, + uno::makeAny( aPropsToObtain ) ); + + uno::Reference< sdbc::XRow > xRow; + xCommandProcessorT->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow; + + uno::Sequence< ucb::ContentInfo > aTypesInfo; + bool bGotTypesInfo = false; + + if ( xRow.is() ) + { + uno::Any aValue = xRow->getObject( + 1, uno::Reference< container::XNameAccess >() ); + if ( aValue.hasValue() && ( aValue >>= aTypesInfo ) ) + { + bGotTypesInfo = true; + } + } + + uno::Reference< ucb::XContentCreator > xCreator; + + if ( !bGotTypesInfo ) + { + // Second, try it using XContentCreator interface -> the "old" way (not + // providing the chance to supply an XCommandEnvironment. + + xCreator.set( xTarget, uno::UNO_QUERY ); + + if ( !xCreator.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Folder")), + -1, + uno::makeAny(rContext.aArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_CREATE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( "Target is no XContentCreator!" ), + rContext.xProcessor ); + // Unreachable + } + + aTypesInfo = xCreator->queryCreatableContentsInfo(); + } + + sal_Int32 nCount = aTypesInfo.getLength(); + if ( !nCount ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Folder")), + -1, + uno::makeAny(rContext.aArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_CREATE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( "No types creatable!" ), + rContext.xProcessor ); + // Unreachable + } + + ////////////////////////////////////////////////////////////////////// + // + // (2) Try to find a matching target type for the source object. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< ucb::XContent > xNew; + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + sal_Int32 nAttribs = aTypesInfo[ n ].Attributes; + sal_Bool bMatch = sal_False; + + if ( rContext.aArg.Operation == ucb::TransferCommandOperation_LINK ) + { + // Create link + + if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK ) + { + // Match! + bMatch = sal_True; + } + } + else if ( ( rContext.aArg.Operation + == ucb::TransferCommandOperation_COPY ) || + ( rContext.aArg.Operation + == ucb::TransferCommandOperation_MOVE ) ) + { + // Copy / Move + + // Is source a link? Create link in target folder then. + if ( bSourceIsLink ) + { + if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK ) + { + // Match! + bMatch = sal_True; + } + } + else + { + // (not a and not b) or (a and b) + // not( a or b) or (a and b) + // + if ( ( !!bSourceIsFolder == + !!( nAttribs + & ucb::ContentInfoAttribute::KIND_FOLDER ) ) + && + ( !!bSourceIsDocument == + !!( nAttribs + & ucb::ContentInfoAttribute::KIND_DOCUMENT ) ) + ) + { + // Match! + bMatch = sal_True; + } + } + } + else + { + ucbhelper::cancelCommandExecution( + uno::makeAny( lang::IllegalArgumentException( + rtl::OUString::createFromAscii( + "Unknown transfer operation!" ), + rContext.xProcessor, + -1 ) ), + rContext.xOrigEnv ); + // Unreachable + } + + if ( bMatch ) + { + ////////////////////////////////////////////////////////////// + // + // (3) Create a new, empty object of matched type. + // + ////////////////////////////////////////////////////////////// + + if ( !xCreator.is() ) + { + // First, try it using "CreatabeleContentsInfo" property and + // "createNewContent" command -> the "new" way. + ucb::Command aCreateNewCommand( + rtl::OUString::createFromAscii( "createNewContent" ), + -1, + uno::makeAny( aTypesInfo[ n ] ) ); + + xCommandProcessorT->execute( aCreateNewCommand, 0, rContext.xEnv ) + >>= xNew; + } + else + { + // Second, try it using XContentCreator interface -> the "old" + // way (not providing the chance to supply an XCommandEnvironment. + + xNew = xCreator->createNewContent( aTypesInfo[ n ] ); + } + + if ( !xNew.is() ) + { + uno::Any aProps + = uno::makeAny( + beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Folder")), + -1, + uno::makeAny(rContext.aArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_CREATE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "createNewContent failed!" ), + rContext.xProcessor ); + // Unreachable + } + break; // escape from 'for' loop + } + } // for + + return xNew; +} + +//========================================================================= +void transferProperties( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS, + const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorN ) + throw( uno::Exception ) +{ + ucb::Command aGetPropertySetInfoCommand( + rtl::OUString::createFromAscii( "getPropertySetInfo" ), + -1, + uno::Any() ); + + uno::Reference< beans::XPropertySetInfo > xInfo; + xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv ) + >>= xInfo; + + if ( !xInfo.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rContext.aArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Unable to get propertyset info from source object!" ), + rContext.xProcessor ); + // Unreachable + } + + uno::Sequence< beans::Property > aAllProps = xInfo->getProperties(); + + ucb::Command aGetPropsCommand1( + rtl::OUString::createFromAscii( "getPropertyValues" ), + -1, + uno::makeAny( aAllProps ) ); + + uno::Reference< sdbc::XRow > xRow1; + xCommandProcessorS->execute( + aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1; + + if ( !xRow1.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rContext.aArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Unable to get properties from source object!" ), + rContext.xProcessor ); + // Unreachable + } + + // Assemble data structure for setPropertyValues command. + + // Note: Make room for additional Title and TargetURL too. -> + 2 + uno::Sequence< beans::PropertyValue > aPropValues( + aAllProps.getLength() + 2 ); + + sal_Bool bHasTitle = ( rContext.aArg.NewTitle.getLength() == 0 ); + sal_Bool bHasTargetURL = ( rContext.aArg.Operation + != ucb::TransferCommandOperation_LINK ); + + sal_Int32 nWritePos = 0; + for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m ) + { + const beans::Property & rCurrProp = aAllProps[ m ]; + beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ]; + + uno::Any aValue; + + if ( rCurrProp.Name.compareToAscii( "Title" ) == 0 ) + { + // Supply new title, if given. + if ( !bHasTitle ) + { + bHasTitle = sal_True; + aValue <<= rContext.aArg.NewTitle; + } + } + else if ( rCurrProp.Name.compareToAscii( "TargetURL" ) == 0 ) + { + // Supply source URL as link target for the new link to create. + if ( !bHasTargetURL ) + { + bHasTargetURL = sal_True; + aValue <<= rContext.aArg.SourceURL; + } + } + + if ( !aValue.hasValue() ) + { + try + { + aValue = xRow1->getObject( + m + 1, uno::Reference< container::XNameAccess >() ); + } + catch ( sdbc::SQLException const & ) + { + // Argh! But try to bring things to an end. Perhaps the + // mad property is not really important... + } + } + + if ( aValue.hasValue() ) + { + rCurrValue.Name = rCurrProp.Name; + rCurrValue.Handle = rCurrProp.Handle; + rCurrValue.Value = aValue; +// rCurrValue.State = + + nWritePos++; + } + } + + // Title needed, but not set yet? + if ( !bHasTitle && ( rContext.aArg.NewTitle.getLength() > 0 ) ) + { + aPropValues[ nWritePos ].Name + = rtl::OUString::createFromAscii( "Title" ); + aPropValues[ nWritePos ].Handle = -1; + aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle; + + nWritePos++; + } + + // TargetURL needed, but not set yet? + if ( !bHasTargetURL && ( rContext.aArg.Operation + == ucb::TransferCommandOperation_LINK ) ) + { + aPropValues[ nWritePos ].Name + = rtl::OUString::createFromAscii( "TargetURL" ); + aPropValues[ nWritePos ].Handle = -1; + aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL; + + nWritePos++; + } + + aPropValues.realloc( nWritePos ); + + // Set properties at new object. + + ucb::Command aSetPropsCommand( + rtl::OUString::createFromAscii( "setPropertyValues" ), + -1, + uno::makeAny( aPropValues ) ); + + xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv ); + + // @@@ What to do with source props that are not supported by the + // new object? addProperty ??? +} + +//========================================================================= +uno::Reference< io::XInputStream > getInputStream( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS ) + throw( uno::Exception ) +{ + uno::Reference< io::XInputStream > xInputStream; + + ////////////////////////////////////////////////////////////////////// + // + // (1) Try to get data as XInputStream via XActiveDataSink. + // + ////////////////////////////////////////////////////////////////////// + + try + { + uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink; + + ucb::OpenCommandArgument2 aArg; + aArg.Mode = ucb::OpenMode::DOCUMENT; + aArg.Priority = 0; // unused + aArg.Sink = xSink; + aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused + + ucb::Command aOpenCommand( + rtl::OUString::createFromAscii( "open" ), + -1, + uno::makeAny( aArg ) ); + + xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ); + xInputStream = xSink->getInputStream(); + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + // will be handled below. + } + + if ( !xInputStream.is() ) + { + ////////////////////////////////////////////////////////////////// + // + // (2) Try to get data via XOutputStream. + // + ////////////////////////////////////////////////////////////////// + + try + { + uno::Reference< io::XOutputStream > xOutputStream( + rContext.xSMgr->createInstance( + rtl::OUString::createFromAscii( "com.sun.star.io.Pipe" ) ), + uno::UNO_QUERY ); + + if ( xOutputStream.is() ) + { + ucb::OpenCommandArgument2 aArg; + aArg.Mode = ucb::OpenMode::DOCUMENT; + aArg.Priority = 0; // unused + aArg.Sink = xOutputStream; + aArg.Properties = uno::Sequence< beans::Property >( 0 ); + + ucb::Command aOpenCommand( + rtl::OUString::createFromAscii( "open" ), + -1, + uno::makeAny( aArg ) ); + + xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ); + + xInputStream = uno::Reference< io::XInputStream >( + xOutputStream, uno::UNO_QUERY ); + } + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( sal_False, "unable to get input stream from document!" ); + } + } + + return xInputStream; +} + +//========================================================================= +uno::Reference< sdbc::XResultSet > getResultSet( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS ) + throw( uno::Exception ) +{ + uno::Reference< sdbc::XResultSet > xResultSet; + + uno::Sequence< beans::Property > aProps( 3 ); + + aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); + aProps[ 0 ].Handle = -1; /* unknown */ + aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" ); + aProps[ 1 ].Handle = -1; /* unknown */ + aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" ); + aProps[ 2 ].Handle = -1; /* unknown */ + + ucb::OpenCommandArgument2 aArg; + aArg.Mode = ucb::OpenMode::ALL; + aArg.Priority = 0; // unused + aArg.Sink = 0; + aArg.Properties = aProps; + + ucb::Command aOpenCommand( rtl::OUString::createFromAscii( "open" ), + -1, + uno::makeAny( aArg ) ); + try + { + uno::Reference< ucb::XDynamicResultSet > xSet; + xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet; + + if ( xSet.is() ) + xResultSet = xSet->getStaticResultSet(); + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( sal_False, "unable to get result set from folder!" ); + } + + return xResultSet; +} + +//========================================================================= +void handleNameClashRename( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XContent > & xNew, + const uno::Reference< + ucb::XCommandProcessor > & xCommandProcessorN, + const uno::Reference< + ucb::XCommandProcessor > & xCommandProcessorS, + /* [inout] */ uno::Reference< io::XInputStream > & xInputStream ) + throw( uno::Exception ) +{ + sal_Int32 nTry = 0; + + // Obtain old title. + uno::Sequence< beans::Property > aProps( 1 ); + aProps[ 0 ].Name = rtl::OUString::createFromAscii( "Title" ); + aProps[ 0 ].Handle = -1; + + ucb::Command aGetPropsCommand( + rtl::OUString::createFromAscii( "getPropertyValues" ), + -1, + uno::makeAny( aProps ) ); + + uno::Reference< sdbc::XRow > xRow; + xCommandProcessorN->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow; + + if ( !xRow.is() ) + { + uno::Any aProps2 + = uno::makeAny( + beans::PropertyValue( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), + -1, + uno::makeAny( + xNew->getIdentifier()->getContentIdentifier() ), + beans::PropertyState_DIRECT_VALUE ) ); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >( &aProps2, 1 ), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Unable to get properties from new object!" ), + rContext.xProcessor ); + // Unreachable + } + + rtl::OUString aOldTitle = xRow->getString( 1 ); + if ( !aOldTitle.getLength() ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( beans::UnknownPropertyException( + rtl::OUString::createFromAscii( + "Unable to get property 'Title' " + "from new object!" ), + rContext.xProcessor ) ), + rContext.xOrigEnv ); + // Unreachable + } + + // Some pseudo-intelligence for not destroying file extensions. + rtl::OUString aOldTitlePre; + rtl::OUString aOldTitlePost; + sal_Int32 nPos = aOldTitle.lastIndexOf( '.' ); + if ( nPos != -1 ) + { + aOldTitlePre = aOldTitle.copy( 0, nPos ); + aOldTitlePost = aOldTitle.copy( nPos ); + } + else + aOldTitlePre = aOldTitle; + + if ( nPos > 0 ) + aOldTitlePre += rtl::OUString::createFromAscii( "_" ); + + sal_Bool bContinue = sal_True; + do + { + nTry++; + + rtl::OUString aNewTitle = aOldTitlePre; + aNewTitle += rtl::OUString::valueOf( nTry ); + aNewTitle += aOldTitlePost; + + // Set new title + setTitle( xCommandProcessorN, rContext.xEnv, aNewTitle ); + + // Retry inserting the content. + try + { + // Previous try may have read from stream. Seek to begin (if + // optional interface XSeekable is supported) or get a new stream. + if ( xInputStream.is() ) + { + uno::Reference< io::XSeekable > xSeekable( + xInputStream, uno::UNO_QUERY ); + if ( xSeekable.is() ) + { + try + { + xSeekable->seek( 0 ); + } + catch ( lang::IllegalArgumentException const & ) + { + xInputStream.clear(); + } + catch ( io::IOException const & ) + { + xInputStream.clear(); + } + } + else + xInputStream.clear(); + + if ( !xInputStream.is() ) + { + xInputStream + = getInputStream( rContext, xCommandProcessorS ); + if ( !xInputStream.is() ) + { + uno::Any aProps2 + = uno::makeAny( + beans::PropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), + -1, + uno::makeAny( + xNew->getIdentifier()-> + getContentIdentifier() ), + beans::PropertyState_DIRECT_VALUE ) ); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >( &aProps2, 1 ), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Got no data stream from source!" ), + rContext.xProcessor ); + // Unreachable + } + } + } + + ucb::InsertCommandArgument aArg; + aArg.Data = xInputStream; + aArg.ReplaceExisting = sal_False; + + ucb::Command aInsertCommand( + rtl::OUString::createFromAscii( "insert" ), + -1, + uno::makeAny( aArg ) ); + + xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv ); + + // Success! + bContinue = sal_False; + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + } + } + while ( bContinue && ( nTry < 50 ) ); + + if ( nTry == 50 ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( + ucb::UnsupportedNameClashException( + rtl::OUString::createFromAscii( + "Unable to resolve name clash!" ), + rContext.xProcessor, + ucb::NameClash::RENAME ) ), + rContext.xOrigEnv ); + // Unreachable + } +} + +//========================================================================= +void globalTransfer_( + const TransferCommandContext & rContext, + const uno::Reference< ucb::XContent > & xSource, + const uno::Reference< ucb::XContent > & xTarget, + const uno::Reference< sdbc::XRow > & xSourceProps ) + throw( uno::Exception ) +{ + // IsFolder: property is required. + sal_Bool bSourceIsFolder = xSourceProps->getBoolean( 1 ); + if ( !bSourceIsFolder && xSourceProps->wasNull() ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( beans::UnknownPropertyException( + rtl::OUString::createFromAscii( + "Unable to get property 'IsFolder' " + "from source object!" ), + rContext.xProcessor ) ), + rContext.xOrigEnv ); + // Unreachable + } + + // IsDocument: property is required. + sal_Bool bSourceIsDocument = xSourceProps->getBoolean( 2 ); + if ( !bSourceIsDocument && xSourceProps->wasNull() ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( beans::UnknownPropertyException( + rtl::OUString::createFromAscii( + "Unable to get property 'IsDocument' " + "from source object!" ), + rContext.xProcessor ) ), + rContext.xOrigEnv ); + // Unreachable + } + + // TargetURL: property is optional. + sal_Bool bSourceIsLink = ( xSourceProps->getString( 3 ).getLength() > 0 ); + + ////////////////////////////////////////////////////////////////////// + // + // (1) Try to find a matching target type for the source object and + // create a new, empty object of that type. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< ucb::XContent > xNew = createNew( rContext, + xTarget, + bSourceIsFolder, + bSourceIsDocument, + bSourceIsLink ); + if ( !xNew.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Folder")), + -1, + uno::makeAny(rContext.aArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_CREATE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "No matching content type at target!" ), + rContext.xProcessor ); + // Unreachable + } + + ////////////////////////////////////////////////////////////////////// + // + // (2) Transfer property values from source to new object. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< ucb::XCommandProcessor > xCommandProcessorN( + xNew, uno::UNO_QUERY ); + if ( !xCommandProcessorN.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny( + xNew->getIdentifier()-> + getContentIdentifier()), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_WRITE, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "New content is not a XCommandProcessor!" ), + rContext.xProcessor ); + // Unreachable + } + + // Obtain all properties from source. + + uno::Reference< ucb::XCommandProcessor > xCommandProcessorS( + xSource, uno::UNO_QUERY ); + if ( !xCommandProcessorS.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rContext.aArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Source content is not a XCommandProcessor!" ), + rContext.xProcessor ); + // Unreachable + } + + transferProperties( rContext, xCommandProcessorS, xCommandProcessorN ); + + ////////////////////////////////////////////////////////////////////// + // + // (3) Try to obtain a data stream from source. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< io::XInputStream > xInputStream; + + if ( bSourceIsDocument && ( rContext.aArg.Operation + != ucb::TransferCommandOperation_LINK ) ) + xInputStream = getInputStream( rContext, xCommandProcessorS ); + + ////////////////////////////////////////////////////////////////////// + // + // (4) Try to obtain a resultset (children) from source. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< sdbc::XResultSet > xResultSet; + + if ( bSourceIsFolder && ( rContext.aArg.Operation + != ucb::TransferCommandOperation_LINK ) ) + xResultSet = getResultSet( rContext, xCommandProcessorS ); + + ////////////////////////////////////////////////////////////////////// + // + // (5) Insert (store) new content. + // + ////////////////////////////////////////////////////////////////////// + + ucb::InsertCommandArgument aArg; + aArg.Data = xInputStream; + + switch ( rContext.aArg.NameClash ) + { + case ucb::NameClash::OVERWRITE: + aArg.ReplaceExisting = sal_True; + break; + + case ucb::NameClash::ERROR: + case ucb::NameClash::RENAME: + case ucb::NameClash::KEEP: // deprecated + case ucb::NameClash::ASK: + aArg.ReplaceExisting = sal_False; + break; + + default: + aArg.ReplaceExisting = sal_False; + OSL_ENSURE( sal_False, "Unknown nameclash directive!" ); + break; + } + + rtl::OUString aDesiredName = createDesiredName( rContext.aArg ); + + bool bRetry; + do + { + bRetry = false; + + try + { + ucb::Command aInsertCommand( + rtl::OUString::createFromAscii( "insert" ), + -1, + uno::makeAny( aArg ) ); + + xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv ); + } + catch ( ucb::UnsupportedNameClashException const & exc ) + { + OSL_ENSURE( !aArg.ReplaceExisting, + "BUG: UnsupportedNameClashException not allowed here!" ); + + if (exc.NameClash != ucb::NameClash::ERROR) { + OSL_ENSURE( false, "BUG: NameClash::ERROR expected!" ); + } + + // No chance to solve name clashes, because I'm not able to detect + // whether there is one. + throw ucb::UnsupportedNameClashException( + rtl::OUString::createFromAscii( + "Unable to resolve name clashes, no chance to detect " + "that there is one!" ), + rContext.xProcessor, + rContext.aArg.NameClash ); + } + catch ( ucb::NameClashException const & ) + { + // The 'insert' command throws a NameClashException if the parameter + // ReplaceExisting of the command's argument was set to false and + // there exists a resource with a clashing name in the target folder + // of the operation. + + // 'insert' command has no direct support for name clashes other + // than ERROR ( ReplaceExisting == false ) and OVERWRITE + // ( ReplaceExisting == true ). So we have to implement the + // other name clash handling directives on top of the content. + + // @@@ 'insert' command should be extended that it accepts a + // name clash handling directive, exactly like 'transfer' command. + + switch ( rContext.aArg.NameClash ) + { + case ucb::NameClash::OVERWRITE: + { + ucbhelper::cancelCommandExecution( + uno::makeAny( + ucb::UnsupportedNameClashException( + rtl::OUString::createFromAscii( + "BUG: insert + replace == true MUST NOT " + "throw NameClashException." ), + rContext.xProcessor, + rContext.aArg.NameClash ) ), + rContext.xOrigEnv ); + // Unreachable + } + + case ucb::NameClash::ERROR: + throw; + + case ucb::NameClash::RENAME: + { + // "invent" a new valid title. + handleNameClashRename( rContext, + xNew, + xCommandProcessorN, + xCommandProcessorS, + xInputStream ); + break; + } + + case ucb::NameClash::ASK: + { + uno::Any aExc; + rtl::OUString aNewTitle; + NameClashContinuation eCont + = interactiveNameClashResolve( + rContext.xOrigEnv, // always use original environment! + rContext.aArg.TargetURL, // target folder URL + aDesiredName, + aExc, + aNewTitle ); + + switch ( eCont ) + { + case NOT_HANDLED: + // Not handled. + cppu::throwException( aExc ); + // break; + + case UNKNOWN: + // Handled, but not clear, how... + // fall-thru intended. + + case ABORT: + throw ucb::CommandFailedException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "abort requested via interaction " + "handler" ) ), + uno::Reference< uno::XInterface >(), + aExc ); + // break; + + case OVERWRITE: + OSL_ENSURE( aArg.ReplaceExisting == sal_False, + "Hu? ReplaceExisting already true?" + ); + aArg.ReplaceExisting = sal_True; + bRetry = true; + break; + + case NEW_NAME: + { + // set new name -> set "Title" property... + if ( setTitle( xCommandProcessorN, + rContext.xEnv, + aNewTitle ) ) + { + // remember suggested title... + aDesiredName = aNewTitle; + + // ... and try again. + bRetry = true; + } + else + { + // error setting title. Abort. + throw ucb::CommandFailedException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "error setting Title property!" + ) ), + uno::Reference< uno::XInterface >(), + aExc ); + } + break; + } + } + + OSL_ENSURE( bRetry, "bRetry must be true here!!!" ); + } + break; + + case ucb::NameClash::KEEP: // deprecated + default: + { + ucbhelper::cancelCommandExecution( + uno::makeAny( + ucb::UnsupportedNameClashException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "default action, don't know how to " + "handle name clash" ) ), + rContext.xProcessor, + rContext.aArg.NameClash ) ), + rContext.xOrigEnv ); + // Unreachable + } + } + } + } + while ( bRetry ); + + ////////////////////////////////////////////////////////////////////// + // + // (6) Process children of source. + // + ////////////////////////////////////////////////////////////////////// + + if ( xResultSet.is() ) + { + try + { + // Iterate over children... + + uno::Reference< sdbc::XRow > xChildRow( + xResultSet, uno::UNO_QUERY ); + + if ( !xChildRow.is() ) + { + uno::Any aProps + = uno::makeAny( + beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rContext.aArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Unable to get properties from children of source!" ), + rContext.xProcessor ); + // Unreachable + } + + uno::Reference< ucb::XContentAccess > xChildAccess( + xResultSet, uno::UNO_QUERY ); + + if ( !xChildAccess.is() ) + { + uno::Any aProps + = uno::makeAny( + beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rContext.aArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + rContext.xOrigEnv, + rtl::OUString::createFromAscii( + "Unable to get children of source!" ), + rContext.xProcessor ); + // Unreachable + } + + if ( xResultSet->first() ) + { + ucb::GlobalTransferCommandArgument aTransArg( + rContext.aArg.Operation, // Operation + rtl::OUString(), // SourceURL; filled later + xNew->getIdentifier() + ->getContentIdentifier(), // TargetURL + rtl::OUString(), // NewTitle; + rContext.aArg.NameClash ); // NameClash + + TransferCommandContext aSubCtx( + rContext.xSMgr, + rContext.xProcessor, + rContext.xEnv, + rContext.xOrigEnv, + aTransArg ); + do + { + uno::Reference< ucb::XContent > xChild + = xChildAccess->queryContent(); + if ( xChild.is() ) + { + // Recursion! + + aSubCtx.aArg.SourceURL + = xChild->getIdentifier()->getContentIdentifier(); + + globalTransfer_( aSubCtx, + xChild, + xNew, + xChildRow ); + } + } + while ( xResultSet->next() ); + } + } + catch ( sdbc::SQLException const & ) + { + } + } + + try { + uno::Reference< ucb::XCommandProcessor > xcp( + xTarget, uno::UNO_QUERY ); + + uno::Any aAny; + uno::Reference< ucb::XCommandInfo > xci; + if(xcp.is()) + aAny = + xcp->execute( + ucb::Command( + rtl::OUString::createFromAscii("getCommandInfo"), + -1, + uno::Any()), + 0, + rContext.xEnv ); + + const rtl::OUString cmdName = + rtl::OUString::createFromAscii("flush"); + if((aAny >>= xci) && xci->hasCommandByName(cmdName)) + xcp->execute( + ucb::Command( + cmdName, + -1, + uno::Any()) , + 0, + rContext.xEnv ); + } + catch( uno::Exception const & ) + { + } +} + +} /* namescpace */ + +//========================================================================= +// +// UniversalContentBroker implementation ( XCommandProcessor commands ). +// +//========================================================================= + +uno::Reference< ucb::XCommandInfo > +UniversalContentBroker::getCommandInfo() +{ + return uno::Reference< ucb::XCommandInfo >( new CommandProcessorInfo() ); +} + +//========================================================================= +void UniversalContentBroker::globalTransfer( + const ucb::GlobalTransferCommandArgument & rArg, + const uno::Reference< ucb::XCommandEnvironment > & xEnv ) + throw( uno::Exception ) +{ + // Use own command environment with own interaction handler intercepting + // some interaction requests that shall not be handled by the user-supplied + // interaction handler. + uno::Reference< ucb::XCommandEnvironment > xLocalEnv; + if (xEnv.is()) + { + uno::Reference< beans::XPropertySet > const xProps( + m_xSMgr, uno::UNO_QUERY_THROW ); + uno::Reference< uno::XComponentContext > xCtx; + xCtx.set( xProps->getPropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), + uno::UNO_QUERY_THROW ); + + xLocalEnv.set( ucb::CommandEnvironment::create( + xCtx, + new InteractionHandlerProxy( xEnv->getInteractionHandler() ), + xEnv->getProgressHandler() ) ); + } + + ////////////////////////////////////////////////////////////////////// + // + // (1) Try to transfer the content using 'transfer' command. + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< ucb::XContent > xTarget; + uno::Reference< ucb::XContentIdentifier > xId + = createContentIdentifier( rArg.TargetURL ); + if ( xId.is() ) + { + try + { + xTarget = queryContent( xId ); + } + catch ( ucb::IllegalIdentifierException const & ) + { + } + } + + if ( !xTarget.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + xEnv, + rtl::OUString::createFromAscii( + "Can't instanciate target object!" ), + this ); + // Unreachable + } + + if ( ( rArg.Operation == ucb::TransferCommandOperation_COPY ) || + ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) ) + { + uno::Reference< ucb::XCommandProcessor > xCommandProcessor( + xTarget, uno::UNO_QUERY ); + if ( !xCommandProcessor.is() ) + { + uno::Any aProps + = uno::makeAny( + beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rArg.TargetURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + xEnv, + rtl::OUString::createFromAscii( + "Target content is not a XCommandProcessor!" ), + this ); + // Unreachable + } + + ucb::TransferInfo aTransferArg( + ( rArg.Operation + == ucb::TransferCommandOperation_MOVE ), // MoveData + rArg.SourceURL, // SourceURL + rArg.NewTitle, // NewTitle + rArg.NameClash ); // NameClash + + bool bRetry; + do + { + bRetry = false; + + try + { + ucb::Command aCommand( + rtl::OUString::createFromAscii( "transfer" ), // Name + -1, // Handle + uno::makeAny( aTransferArg ) ); // Argument + + xCommandProcessor->execute( aCommand, 0, xLocalEnv ); + + // Command succeeded. We're done. + return; + } + catch ( ucb::InteractiveBadTransferURLException const & ) + { + // Source URL is not supported by target. Try to transfer + // the content "manually". + } + catch ( ucb::UnsupportedCommandException const & ) + { + // 'transfer' command is not supported by commandprocessor. + // Try to transfer manually. + } + catch ( ucb::UnsupportedNameClashException const & exc ) + { + OSL_ENSURE( aTransferArg.NameClash == exc.NameClash, + "nameclash mismatch!" ); + if ( exc.NameClash == ucb::NameClash::ASK ) + { + // Try to detect a name clash by invoking "transfer" with + // NameClash::ERROR. + try + { + ucb::TransferInfo aTransferArg1( + aTransferArg.MoveData, + aTransferArg.SourceURL, + aTransferArg.NewTitle, + ucb::NameClash::ERROR ); + + ucb::Command aCommand1( + rtl::OUString::createFromAscii( "transfer" ), + -1, + uno::makeAny( aTransferArg1 ) ); + + xCommandProcessor->execute( aCommand1, 0, xLocalEnv ); + + // Command succeeded. We're done. + return; + } + catch ( ucb::UnsupportedNameClashException const & ) + { + // No chance to solve name clashes, because I'm not + // able to detect whether there is one. + throw exc; // Not just 'throw;'! + } + catch ( ucb::NameClashException const & ) + { + // There's a clash. Use interaction handler to solve it. + + uno::Any aExc; + rtl::OUString aNewTitle; + NameClashContinuation eCont + = interactiveNameClashResolve( + xEnv, // always use original environment! + rArg.TargetURL, // target folder URL + createDesiredName( + aTransferArg ), // clashing name + aExc, + aNewTitle ); + + switch ( eCont ) + { + case NOT_HANDLED: + // Not handled. + cppu::throwException( aExc ); +// break; + + case UNKNOWN: + // Handled, but not clear, how... + // fall-thru intended. + + case ABORT: + throw ucb::CommandFailedException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "abort requested via interaction " + "handler" ) ), + uno::Reference< uno::XInterface >(), + aExc ); +// break; + + case OVERWRITE: + aTransferArg.NameClash + = ucb::NameClash::OVERWRITE; + bRetry = true; + break; + + case NEW_NAME: + aTransferArg.NewTitle = aNewTitle; + bRetry = true; + break; + } + + OSL_ENSURE( bRetry, "bRetry must be true here!!!" ); + } + } + else + { + throw; + } + } + } + while ( bRetry ); + } + + ////////////////////////////////////////////////////////////////////// + // + // (2) Try to transfer the content "manually". + // + ////////////////////////////////////////////////////////////////////// + + uno::Reference< ucb::XContent > xSource; + try + { + uno::Reference< ucb::XContentIdentifier > xId2 + = createContentIdentifier( rArg.SourceURL ); + if ( xId2.is() ) + xSource = queryContent( xId2 ); + } + catch ( ucb::IllegalIdentifierException const & ) + { + // Error handling via "if ( !xSource.is() )" below. + } + + if ( !xSource.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + xEnv, + rtl::OUString::createFromAscii( + "Can't instanciate source object!" ), + this ); + // Unreachable + } + + uno::Reference< ucb::XCommandProcessor > xCommandProcessor( + xSource, uno::UNO_QUERY ); + if ( !xCommandProcessor.is() ) + { + uno::Any aProps + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps, 1), + xEnv, + rtl::OUString::createFromAscii( + "Source content is not a XCommandProcessor!" ), + this ); + // Unreachable + } + + // Obtain interesting property values from source... + + uno::Sequence< beans::Property > aProps( 4 ); + + aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); + aProps[ 0 ].Handle = -1; /* unknown */ + aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" ); + aProps[ 1 ].Handle = -1; /* unknown */ + aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" ); + aProps[ 2 ].Handle = -1; /* unknown */ + aProps[ 3 ].Name = rtl::OUString::createFromAscii( "BaseURI" ); + aProps[ 3 ].Handle = -1; /* unknown */ + + ucb::Command aGetPropsCommand( + rtl::OUString::createFromAscii( "getPropertyValues" ), + -1, + uno::makeAny( aProps ) ); + + uno::Reference< sdbc::XRow > xRow; + xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow; + + if ( !xRow.is() ) + { + uno::Any aProps2 + = uno::makeAny(beans::PropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "Uri")), + -1, + uno::makeAny(rArg.SourceURL), + beans::PropertyState_DIRECT_VALUE)); + ucbhelper::cancelCommandExecution( + ucb::IOErrorCode_CANT_READ, + uno::Sequence< uno::Any >(&aProps2, 1), + xEnv, + rtl::OUString::createFromAscii( + "Unable to get properties from source object!" ), + this ); + // Unreachable + } + + TransferCommandContext aTransferCtx( + m_xSMgr, this, xLocalEnv, xEnv, rArg ); + + if ( rArg.NewTitle.getLength() == 0 ) + { + // BaseURI: property is optional. + rtl::OUString aBaseURI( xRow->getString( 4 ) ); + if ( aBaseURI.getLength() ) + { + aTransferCtx.aArg.NewTitle + = createDesiredName( aBaseURI, rtl::OUString() ); + } + } + + // Do it! + globalTransfer_( aTransferCtx, xSource, xTarget, xRow ); + + ////////////////////////////////////////////////////////////////////// + // + // (3) Delete source, if operation is MOVE. + // + ////////////////////////////////////////////////////////////////////// + + if ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) + { + try + { + ucb::Command aCommand( + rtl::OUString::createFromAscii( "delete" ), // Name + -1, // Handle + uno::makeAny( sal_Bool( sal_True ) ) ); // Argument + + xCommandProcessor->execute( aCommand, 0, xLocalEnv ); + } + catch ( uno::Exception const & ) + { + OSL_ENSURE( sal_False, "Cannot delete source object!" ); + throw; + } + } +} diff --git a/ucb/source/core/ucbcmds.hxx b/ucb/source/core/ucbcmds.hxx new file mode 100644 index 000000000000..7e50bcceef93 --- /dev/null +++ b/ucb/source/core/ucbcmds.hxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * 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 _UCBCMDS_HXX +#define _UCBCMDS_HXX + +////////////////////////////////////////////////////////////////////////// +// +// Definitions for the commands supported by the UCB. +// +////////////////////////////////////////////////////////////////////////// + +#define GETCOMMANDINFO_NAME "getCommandInfo" +#define GETCOMMANDINFO_HANDLE 1024 + +#define GLOBALTRANSFER_NAME "globalTransfer" +#define GLOBALTRANSFER_HANDLE 1025 + +#endif /* !_UCBCMDS_HXX */ diff --git a/ucb/source/core/ucbprops.cxx b/ucb/source/core/ucbprops.cxx new file mode 100644 index 000000000000..564383fd528a --- /dev/null +++ b/ucb/source/core/ucbprops.cxx @@ -0,0 +1,477 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" +#include <osl/diagnose.h> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/ucb/CrossReference.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/ucb/DocumentHeaderField.hpp> +#include <com/sun/star/ucb/RecipientInfo.hpp> +#include <com/sun/star/ucb/RuleSet.hpp> +#include <com/sun/star/ucb/SendInfo.hpp> +#include <com/sun/star/ucb/SendMediaTypes.hpp> +#include <com/sun/star/ucb/XDataContainer.hpp> +#include "ucbprops.hxx" + +using namespace rtl; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; + +//========================================================================= +// +// struct PropertyTableEntry +// +//========================================================================= + +struct PropertyTableEntry +{ + const char* pName; + sal_Int32 nHandle; + sal_Int16 nAttributes; + const com::sun::star::uno::Type& (*pGetCppuType)(); +}; + +////////////////////////////////////////////////////////////////////////// +// +// CPPU type access functions. +// +////////////////////////////////////////////////////////////////////////// + +static const com::sun::star::uno::Type& OUString_getCppuType() +{ + return getCppuType( static_cast< const rtl::OUString * >( 0 ) ); +} + +static const com::sun::star::uno::Type& sal_uInt16_getCppuType() +{ + // ! uInt -> Int, because of Java !!! + return getCppuType( static_cast< const sal_Int16 * >( 0 ) ); +} + +static const com::sun::star::uno::Type& sal_uInt32_getCppuType() +{ + // ! uInt -> Int, because of Java !!! + return getCppuType( static_cast< const sal_Int32 * >( 0 ) ); +} + +static const com::sun::star::uno::Type& sal_uInt64_getCppuType() +{ + // ! uInt -> Int, because of Java !!! + return getCppuType( static_cast< const sal_Int64 * >( 0 ) ); +} + +static const com::sun::star::uno::Type& enum_getCppuType() +{ + // ! enum -> Int, because of Java !!! + return getCppuType( static_cast< const sal_Int16 * >( 0 ) ); +} + +static const com::sun::star::uno::Type& sal_Bool_getCppuType() +{ + return getCppuBooleanType(); +} + +static const com::sun::star::uno::Type& byte_getCppuType() +{ + return getCppuType( static_cast< const sal_Int8 * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_CrossReference_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< + com::sun::star::ucb::CrossReference > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& DateTime_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::util::DateTime * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_byte_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< sal_Int8 > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_DocumentHeaderField_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< + com::sun::star::ucb::DocumentHeaderField > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& XDataContainer_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Reference< + com::sun::star::ucb::XDataContainer > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_RecipientInfo_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< + com::sun::star::ucb::RecipientInfo > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& RuleSet_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::ucb::RuleSet * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_SendInfo_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< + com::sun::star::ucb::SendInfo > * >( 0 ) ); +} + +static const com::sun::star::uno::Type& Sequence_SendMediaTypes_getCppuType() +{ + return getCppuType( + static_cast< com::sun::star::uno::Sequence< + com::sun::star::ucb::SendMediaTypes > * >( 0 ) ); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// A table with all well-known UCB properties. +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define ATTR_DEFAULT ( PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID | PropertyAttribute::MAYBEDEFAULT ) + +static PropertyTableEntry __aPropertyTable[] = +{ + { "Account", -1 /* WID_ACCOUNT */, ATTR_DEFAULT, &OUString_getCppuType }, + { "AutoUpdateInterval", -1 /* WID_AUTOUPDATE_INTERVAL */, ATTR_DEFAULT, &sal_uInt32_getCppuType }, + { "ConfirmEmpty", -1 /* WID_TRASHCAN_FLAG_CONFIRMEMPTY */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "ConnectionLimit", -1 /* WID_HTTP_CONNECTION_LIMIT */, ATTR_DEFAULT, &byte_getCppuType }, + { "ConnectionMode", -1 /* WID_CONNECTION_MODE */, ATTR_DEFAULT, &enum_getCppuType }, + { "ContentCountLimit", -1 /* WID_SHOW_MSGS_TIMELIMIT */, ATTR_DEFAULT, &sal_uInt16_getCppuType }, + { "ContentType", -1 /* WID_CONTENT_TYPE */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Cookie", -1 /* WID_HTTP_COOKIE */, ATTR_DEFAULT, &OUString_getCppuType }, + { "CrossReferences", -1 /* WID_NEWS_XREFLIST */, ATTR_DEFAULT, &Sequence_CrossReference_getCppuType }, + { "DateCreated", -1 /* WID_DATE_CREATED */, ATTR_DEFAULT, &DateTime_getCppuType }, + { "DateModified", -1 /* WID_DATE_MODIFIED */, ATTR_DEFAULT, &DateTime_getCppuType }, + { "DeleteOnServer", -1 /* WID_DELETE_ON_SERVER */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "DocumentBody", -1 /* WID_DOCUMENT_BODY */, ATTR_DEFAULT, &Sequence_byte_getCppuType }, + { "DocumentCount", -1 /* WID_TOTALCONTENTCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt32_getCppuType }, + { "DocumentCountMarked", + -1 /* WID_MARKED_DOCUMENT_COUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt32_getCppuType }, + { "DocumentHeader", -1 /* WID_DOCUMENT_HEADER */, ATTR_DEFAULT, &Sequence_DocumentHeaderField_getCppuType }, + { "DocumentStoreMode", -1 /* WID_MESSAGE_STOREMODE */, ATTR_DEFAULT, &enum_getCppuType }, + { "DocumentViewMode", -1 /* WID_MESSAGEVIEW_MODE */, ATTR_DEFAULT, &enum_getCppuType }, + { "FTPAccount", -1 /* WID_FTP_ACCOUNT */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Flags", -1 /* WID_FSYS_FLAGS */, ATTR_DEFAULT, &sal_uInt32_getCppuType }, + { "FolderCount", -1 /* WID_FOLDER_COUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt32_getCppuType }, + { "FolderViewMode", -1 /* WID_FOLDERVIEW_MODE */, ATTR_DEFAULT, &enum_getCppuType }, + { "FreeSpace", -1 /* WID_FSYS_DISKSPACE_LEFT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt64_getCppuType }, + { "HasDocuments", -1 /* WID_FLAG_HAS_MESSAGES */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_Bool_getCppuType }, + { "HasFolders", -1 /* WID_FLAG_HAS_FOLDER */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_Bool_getCppuType }, + { "IsAutoDelete", -1 /* WID_TRASHCAN_FLAG_AUTODELETE */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsAutoUpdate", -1 /* WID_UPDATE_ENABLED */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsDocument", -1 /* WID_FLAG_IS_MESSAGE */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_Bool_getCppuType }, + { "IsFolder", -1 /* WID_FLAG_IS_FOLDER */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_Bool_getCppuType }, + { "IsKeepExpired", -1 /* WID_HTTP_KEEP_EXPIRED */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsLimitedContentCount", + -1 /* WID_SHOW_MSGS_HAS_TIMELIMIT */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsMarked", -1 /* WID_IS_MARKED */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsRead", -1 /* WID_IS_READ */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsReadOnly", -1 /* WID_FLAG_READONLY */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsSubscribed", -1 /* WID_FLAG_SUBSCRIBED */, ATTR_DEFAULT, &sal_Bool_getCppuType }, +// { "IsThreaded", -1 /* WID_THREADED */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "IsTimeLimitedStore", -1 /* WID_STORE_MSGS_HAS_TIMELIMIT */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "Keywords", -1 /* WID_KEYWORDS */, ATTR_DEFAULT, &OUString_getCppuType }, + { "LocalBase", -1 /* WID_LOCALBASE */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageBCC", -1 /* WID_BCC */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageBody", -1 /* WID_MESSAGEBODY */, ATTR_DEFAULT, &XDataContainer_getCppuType }, + { "MessageCC", -1 /* WID_CC */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageFrom", -1 /* WID_FROM */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageId", -1 /* WID_MESSAGE_ID */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageInReplyTo", -1 /* WID_IN_REPLY_TO */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageReplyTo", -1 /* WID_REPLY_TO */, ATTR_DEFAULT, &OUString_getCppuType }, + { "MessageTo", -1 /* WID_TO */, ATTR_DEFAULT, &OUString_getCppuType }, + { "NewsGroups", -1 /* WID_NEWSGROUPS */, ATTR_DEFAULT, &OUString_getCppuType }, + { "NoCacheList", -1 /* WID_HTTP_NOCACHE_LIST */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Origin", -1 /* WID_TRASH_ORIGIN */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &OUString_getCppuType }, + { "OutgoingMessageRecipients", + -1 /* WID_RECIPIENTLIST */, ATTR_DEFAULT, &Sequence_RecipientInfo_getCppuType }, + { "OutgoingMessageState", + -1 /* WID_OUTMSGINTERNALSTATE */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &enum_getCppuType }, + { "OutgoingMessageViewMode", + -1 /* WID_SENTMESSAGEVIEW_MODE */, + ATTR_DEFAULT, &enum_getCppuType }, +// { "OwnURL", -1 /* WID_OWN_URL */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Password", -1 /* WID_PASSWORD */, ATTR_DEFAULT, &OUString_getCppuType }, +// { "PresentationURL", -1 /* WID_REAL_URL */, ATTR_DEFAULT | PropertyAttribute::READONLY, +// &OUString_getCppuType }, + { "Priority", -1 /* WID_PRIORITY */, ATTR_DEFAULT, &enum_getCppuType }, + { "References", -1 /* WID_REFERENCES */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Referer", -1 /* WID_HTTP_REFERER */, ATTR_DEFAULT, &OUString_getCppuType }, + { "Rules", -1 /* WID_RULES */, ATTR_DEFAULT, &RuleSet_getCppuType }, + { "SearchCriteria", -1 /* WID_SEARCH_CRITERIA */, ATTR_DEFAULT, &RuleSet_getCppuType }, + { "SearchIndirections", -1 /* WID_SEARCH_INDIRECTIONS */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "SearchLocations", -1 /* WID_SEARCH_LOCATIONS */, ATTR_DEFAULT, &OUString_getCppuType }, + { "SearchRecursive", -1 /* WID_SEARCH_RECURSIVE */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "SeenCount", -1 /* WID_SEENCONTENTCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt32_getCppuType }, + { "SendCopyTarget", -1 /* WID_SEND_COPY_TARGET */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendFormats", -1 /* WID_SEND_FORMATS */, ATTR_DEFAULT, &Sequence_SendMediaTypes_getCppuType }, + { "SendFroms", -1 /* WID_SEND_FROM_DEFAULT */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendPasswords", -1 /* WID_SEND_PASSWORD */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendProtocolPrivate",-1 /* WID_SEND_PRIVATE_PROT_ID */, ATTR_DEFAULT, &sal_uInt16_getCppuType }, + { "SendProtocolPublic", -1 /* WID_SEND_PUBLIC_PROT_ID */, ATTR_DEFAULT, &sal_uInt16_getCppuType }, + { "SendReplyTos", -1 /* WID_SEND_REPLY_TO_DEFAULT */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendServerNames", -1 /* WID_SEND_SERVERNAME */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendUserNames", -1 /* WID_SEND_USERNAME */, ATTR_DEFAULT, &Sequence_SendInfo_getCppuType }, + { "SendVIMPostOfficePath", + -1 /* WID_SEND_VIM_POPATH */, ATTR_DEFAULT, &OUString_getCppuType }, + { "ServerBase", -1 /* WID_SERVERBASE */, ATTR_DEFAULT, &OUString_getCppuType }, + { "ServerName", -1 /* WID_SERVERNAME */, ATTR_DEFAULT, &OUString_getCppuType }, + { "ServerPort", -1 /* WID_SERVERPORT */, ATTR_DEFAULT, &sal_uInt16_getCppuType }, + { "Size", -1 /* WID_DOCUMENT_SIZE */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt64_getCppuType }, + { "SizeLimit", -1 /* WID_SIZE_LIMIT */, ATTR_DEFAULT, &sal_uInt64_getCppuType }, + { "SubscribedCount", -1 /* WID_SUBSCRNEWSGROUPCOUNT */, ATTR_DEFAULT | PropertyAttribute::READONLY, + &sal_uInt32_getCppuType }, + { "SynchronizePolicy", -1 /* WID_WHO_IS_MASTER */, ATTR_DEFAULT, &enum_getCppuType }, + { "TargetFrames", -1 /* WID_TARGET_FRAMES */, ATTR_DEFAULT, &OUString_getCppuType }, + { "TargetURL", -1 /* WID_TARGET_URL */, ATTR_DEFAULT, &OUString_getCppuType }, +// { "ThreadingInfo", -1 /* WID_THREADING */, ATTR_DEFAULT, &Sequence_ThreadingInfo_getCppuType }, + { "TimeLimitStore", -1 /* WID_STORE_MSGS_TIMELIMIT */, ATTR_DEFAULT, &sal_uInt16_getCppuType }, + { "Title", -1 /* WID_TITLE */, ATTR_DEFAULT, &OUString_getCppuType }, + { "UpdateOnOpen", -1 /* WID_FLAG_UPDATE_ON_OPEN */, ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "UseOutBoxPrivateProtocolSettings", + -1 /* WID_SEND_PRIVATE_OUTBOXPROPS */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "UseOutBoxPublicProtocolSettings", + -1 /* WID_SEND_PUBLIC_OUTBOXPROPS */, + ATTR_DEFAULT, &sal_Bool_getCppuType }, + { "UserName", -1 /* WID_USERNAME */, ATTR_DEFAULT, &OUString_getCppuType }, + { "UserSortCriterium", -1 /* WID_USER_SORT_CRITERIUM */, ATTR_DEFAULT, &OUString_getCppuType }, + { "VIMPostOfficePath", -1 /* WID_VIM_POPATH */, ATTR_DEFAULT, &OUString_getCppuType }, + { "VerificationMode", -1 /* WID_HTTP_VERIFY_MODE */, ATTR_DEFAULT, &enum_getCppuType }, + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // EOT. + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + { 0, 0, 0, 0 } +}; + +//========================================================================= +//========================================================================= +// +// UcbPropertiesManager Implementation. +// +//========================================================================= +//========================================================================= + +UcbPropertiesManager::UcbPropertiesManager( + const Reference< XMultiServiceFactory >& ) +: m_pProps( 0 ) +{ +} + +//========================================================================= +// virtual +UcbPropertiesManager::~UcbPropertiesManager() +{ + delete m_pProps; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_3( UcbPropertiesManager, + XTypeProvider, + XServiceInfo, + XPropertySetInfo ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_3( UcbPropertiesManager, + XTypeProvider, + XServiceInfo, + XPropertySetInfo ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_IMPL_1( UcbPropertiesManager, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UcbPropertiesManager" ), + OUString::createFromAscii( + PROPERTIES_MANAGER_SERVICE_NAME ) ); + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbPropertiesManager ); + +//========================================================================= +// +// XPropertySetInfo methods. +// +//========================================================================= + +// virtual +Sequence< Property > SAL_CALL UcbPropertiesManager::getProperties() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( !m_pProps ) + { + m_pProps = new Sequence< Property >( 128 ); + Property* pProps = m_pProps->getArray(); + sal_Int32 nPos = 0; + sal_Int32 nSize = m_pProps->getLength(); + + ////////////////////////////////////////////////////////////////// + // Get info for well-known properties. + ////////////////////////////////////////////////////////////////// + + const PropertyTableEntry* pCurr = &__aPropertyTable[ 0 ]; + while ( pCurr->pName ) + { + if ( nSize <= nPos ) + { + OSL_ENSURE( sal_False, + "UcbPropertiesManager::getProperties - " + "Initial size of property sequence too small!" ); + + m_pProps->realloc( 128 ); + nSize += 128; + } + + Property& rProp = pProps[ nPos ]; + + rProp.Name = OUString::createFromAscii( pCurr->pName ); + rProp.Handle = pCurr->nHandle; + rProp.Type = pCurr->pGetCppuType(); + rProp.Attributes = pCurr->nAttributes; + + nPos++; + pCurr++; + } + + if ( nPos > 0 ) + { + m_pProps->realloc( nPos ); + nSize = m_pProps->getLength(); + } + } + return *m_pProps; +} + +//========================================================================= +// virtual +Property SAL_CALL UcbPropertiesManager::getPropertyByName( const OUString& aName ) + throw( UnknownPropertyException, RuntimeException ) +{ + Property aProp; + if ( queryProperty( aName, aProp ) ) + return aProp; + + throw UnknownPropertyException(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL UcbPropertiesManager::hasPropertyByName( const OUString& Name ) + throw( RuntimeException ) +{ + Property aProp; + return queryProperty( Name, aProp ); +} + +//========================================================================= +// +// Non-Interface methods. +// +//========================================================================= + +sal_Bool UcbPropertiesManager::queryProperty( + const OUString& rName, Property& rProp ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + getProperties(); + + const Property* pProps = m_pProps->getConstArray(); + sal_Int32 nCount = m_pProps->getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const Property& rCurrProp = pProps[ n ]; + if ( rCurrProp.Name == rName ) + { + rProp = rCurrProp; + return sal_True; + } + } + + return sal_False; +} + diff --git a/ucb/source/core/ucbprops.hxx b/ucb/source/core/ucbprops.hxx new file mode 100644 index 000000000000..7908fa6af90c --- /dev/null +++ b/ucb/source/core/ucbprops.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * 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 _UCBPROPS_HXX +#define _UCBPROPS_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <cppuhelper/weak.hxx> +#include <osl/mutex.hxx> +#include <ucbhelper/macros.hxx> + +//========================================================================= + +#define PROPERTIES_MANAGER_SERVICE_NAME "com.sun.star.ucb.PropertiesManager" + +//============================================================================ +// +// class UcbPropertiesManager. +// +//============================================================================ + +class UcbPropertiesManager : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::beans::XPropertySetInfo +{ + com::sun::star::uno::Sequence< com::sun::star::beans::Property >* + m_pProps; + osl::Mutex m_aMutex; + +private: + sal_Bool queryProperty( const rtl::OUString& rName, + com::sun::star::beans::Property& rProp ); + +public: + UcbPropertiesManager( const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& + rxSMgr ); + virtual ~UcbPropertiesManager(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_DECL() + + // XPropertySetInfo + virtual com::sun::star::uno::Sequence< + com::sun::star::beans::Property > SAL_CALL + getProperties() + throw( com::sun::star::uno::RuntimeException ); + virtual com::sun::star::beans::Property SAL_CALL + getPropertyByName( const rtl::OUString& aName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::uno::RuntimeException ); + virtual sal_Bool SAL_CALL + hasPropertyByName( const rtl::OUString& Name ) + throw( com::sun::star::uno::RuntimeException ); +}; + +#endif /* !_UCBPROPS_HXX */ + diff --git a/ucb/source/core/ucbserv.cxx b/ucb/source/core/ucbserv.cxx new file mode 100644 index 000000000000..a4e5bdc1dccf --- /dev/null +++ b/ucb/source/core/ucbserv.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * 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 "ucb.hxx" +#include "ucbstore.hxx" +#include "ucbprops.hxx" +#include "provprox.hxx" +#include "cmdenv.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +//========================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//========================================================================= +extern "C" void * SAL_CALL component_getFactory( + const sal_Char * pImplName, void * pServiceManager, void * ) +{ + void * pRet = 0; + + Reference< XMultiServiceFactory > xSMgr( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) ); + Reference< XSingleServiceFactory > xFactory; + + ////////////////////////////////////////////////////////////////////// + // Universal Content Broker. + ////////////////////////////////////////////////////////////////////// + + if ( UniversalContentBroker::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = UniversalContentBroker::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + // UCB Store. + ////////////////////////////////////////////////////////////////////// + + else if ( UcbStore::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = UcbStore::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + // UCB PropertiesManager. + ////////////////////////////////////////////////////////////////////// + + else if ( UcbPropertiesManager::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = UcbPropertiesManager::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + // UCP Proxy Factory. + ////////////////////////////////////////////////////////////////////// + + else if ( UcbContentProviderProxyFactory::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory + = UcbContentProviderProxyFactory::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + // Command Environment. + ////////////////////////////////////////////////////////////////////// + + else if ( ucb_cmdenv::UcbCommandEnvironment::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory + = ucb_cmdenv::UcbCommandEnvironment::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + diff --git a/ucb/source/core/ucbstore.cxx b/ucb/source/core/ucbstore.cxx new file mode 100644 index 000000000000..cd5cb7856d7a --- /dev/null +++ b/ucb/source/core/ucbstore.cxx @@ -0,0 +1,2770 @@ +/************************************************************************* + * + * 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 <list> +#include <hash_map> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertySetInfoChange.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> +#include "ucbstore.hxx" + +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace cppu; +using namespace rtl; + +//========================================================================= +rtl::OUString makeHierarchalNameSegment( const rtl::OUString & rIn ) +{ + rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "['" ); + + sal_Int32 nCount = rIn.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const sal_Unicode c = rIn.getStr()[ n ]; + switch ( c ) + { + case '&': + aBuffer.appendAscii( "&" ); + break; + + case '"': + aBuffer.appendAscii( """ ); + break; + + case '\'': + aBuffer.appendAscii( "'" ); + break; + + case '<': + aBuffer.appendAscii( "<" ); + break; + + case '>': + aBuffer.appendAscii( ">" ); + break; + + default: + aBuffer.append( c ); + break; + } + } + + aBuffer.appendAscii( "']" ); + return rtl::OUString( aBuffer.makeStringAndClear() ); +} + +//========================================================================= + +#define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties" + +// describe path of cfg entry +#define CFGPROPERTY_NODEPATH "nodepath" +// true->async. update; false->sync. update +#define CFGPROPERTY_LAZYWRITE "lazywrite" + +//========================================================================= + +struct equalString_Impl +{ + bool operator()( const OUString& s1, const OUString& s2 ) const + { + return !!( s1 == s2 ); + } +}; + +struct hashString_Impl +{ + size_t operator()( const OUString & rName ) const + { + return rName.hashCode(); + } +}; + +//========================================================================= +// +// PropertySetMap_Impl. +// +//========================================================================= + +typedef std::hash_map +< + OUString, + PersistentPropertySet*, + hashString_Impl, + equalString_Impl +> +PropertySetMap_Impl; + +//========================================================================= +// +// class PropertySetInfo_Impl +// +//========================================================================= + +class PropertySetInfo_Impl : + public OWeakObject, public XTypeProvider, public XPropertySetInfo +{ + Reference< XMultiServiceFactory > m_xSMgr; + Sequence< Property >* m_pProps; + PersistentPropertySet* m_pOwner; + +public: + PropertySetInfo_Impl( const Reference< XMultiServiceFactory >& rxSMgr, + PersistentPropertySet* pOwner ); + virtual ~PropertySetInfo_Impl(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties() + throw( RuntimeException ); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) + throw( UnknownPropertyException, RuntimeException ); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) + throw( RuntimeException ); + + // Non-interface methods. + void reset() { delete m_pProps; m_pProps = 0; } +}; + +//========================================================================= +// +// UcbStore_Impl. +// +//========================================================================= + +struct UcbStore_Impl +{ + osl::Mutex m_aMutex; + Sequence< Any > m_aInitArgs; + Reference< XPropertySetRegistry > m_xTheRegistry; +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// UcbStore Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +UcbStore::UcbStore( const Reference< XMultiServiceFactory >& rXSMgr ) +: m_xSMgr( rXSMgr ), + m_pImpl( new UcbStore_Impl() ) +{ +} + +//========================================================================= +// virtual +UcbStore::~UcbStore() +{ + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_4( UcbStore, + XTypeProvider, + XServiceInfo, + XPropertySetRegistryFactory, + XInitialization ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_4( UcbStore, + XTypeProvider, + XServiceInfo, + XPropertySetRegistryFactory, + XInitialization ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_IMPL_1( UcbStore, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UcbStore" ), + OUString::createFromAscii( + STORE_SERVICE_NAME ) ); + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore ); + +//========================================================================= +// +// XPropertySetRegistryFactory methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetRegistry > SAL_CALL +UcbStore::createPropertySetRegistry( const OUString& ) + throw( RuntimeException ) +{ + // The URL parameter is ignored by this interface implementation. It always + // uses the configuration server as storage medium. + + if ( !m_pImpl->m_xTheRegistry.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_xTheRegistry.is() ) + m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xSMgr, getInitArgs() ); + } + + return m_pImpl->m_xTheRegistry; +} + +//========================================================================= +// +// XInitialization methods. +// +//========================================================================= + +// virtual +void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments ) + throw( Exception, RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + m_pImpl->m_aInitArgs = aArguments; +} + +//========================================================================= +const Sequence< Any >& UcbStore::getInitArgs() const +{ + return m_pImpl->m_aInitArgs; +} + +//========================================================================= +// +// PropertySetRegistry_Impl. +// +//========================================================================= + +struct PropertySetRegistry_Impl +{ + const Sequence< Any > m_aInitArgs; + PropertySetMap_Impl m_aPropSets; + Reference< XMultiServiceFactory > m_xConfigProvider; + Reference< XInterface > m_xRootReadAccess; + Reference< XInterface > m_xRootWriteAccess; + osl::Mutex m_aMutex; + sal_Bool m_bTriedToGetRootReadAccess; // #82494# + sal_Bool m_bTriedToGetRootWriteAccess; // #82494# + + PropertySetRegistry_Impl( const Sequence< Any > &rInitArgs ) + : m_aInitArgs( rInitArgs ), + m_bTriedToGetRootReadAccess( sal_False ), + m_bTriedToGetRootWriteAccess( sal_False ) + { + } +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// PropertySetRegistry Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +PropertySetRegistry::PropertySetRegistry( + const Reference< XMultiServiceFactory >& rXSMgr, + const Sequence< Any > &rInitArgs ) +: m_xSMgr( rXSMgr ), + m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) ) +{ +} + +//========================================================================= +// virtual +PropertySetRegistry::~PropertySetRegistry() +{ + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_5( PropertySetRegistry, + XTypeProvider, + XServiceInfo, + XPropertySetRegistry, + XElementAccess, /* base of XNameAccess */ + XNameAccess ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_4( PropertySetRegistry, + XTypeProvider, + XServiceInfo, + XPropertySetRegistry, + XNameAccess ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry, + OUString::createFromAscii( + "com.sun.star.comp.ucb.PropertySetRegistry" ), + OUString::createFromAscii( + PROPSET_REG_SERVICE_NAME ) ); + +//========================================================================= +// +// XPropertySetRegistry methods. +// +//========================================================================= + +// virtual +Reference< XPersistentPropertySet > SAL_CALL +PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create ) + throw( RuntimeException ) +{ + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; + + PropertySetMap_Impl::const_iterator it = rSets.find( key ); + if ( it != rSets.end() ) + { + // Already instanciated. + return Reference< XPersistentPropertySet >( (*it).second ); + } + else + { + // Create new instance. + Reference< XNameAccess > xRootNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Propertyset in registry? + if ( xRootNameAccess->hasByName( key ) ) + { + // Yep! + return Reference< XPersistentPropertySet >( + new PersistentPropertySet( + m_xSMgr, *this, key ) ); + } + else if ( create ) + { + // No. Create entry for propertyset. + + Reference< XSingleServiceFactory > xFac( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PropertySetRegistry::openPropertySet - " + "No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::openPropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::openPropertySet - " + "No conteiner!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + try + { + // Create new "Properties" config item. + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Fill new item... + +// // Set Values +// xNameReplace->replaceByName( +// OUString::createFromAscii( "Values" ), +// makeAny( ... ) ); + + // Insert new item. + xContainer->insertByName( + key, makeAny( xNameReplace ) ); + // Commit changes. + xBatch->commitChanges(); + + return Reference< XPersistentPropertySet >( + new PersistentPropertySet( + m_xSMgr, *this, key ) ); + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught IllegalArgumentException!" ); + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught ElementExistException!" ); + } + catch ( WrappedTargetException& ) + { + // insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught WrappedTargetException!" ); + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught RuntimeException!" ); + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught Exception!" ); + } + } + } + else + { + // No entry. Fail, but no error. + return Reference< XPersistentPropertySet >(); + } + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - Error!" ); + } + } + + return Reference< XPersistentPropertySet >(); +} + +//========================================================================= +// virtual +void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key ) + throw( RuntimeException ) +{ + if ( !key.getLength() ) + return; + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xRootNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Propertyset in registry? + if ( !xRootNameAccess->hasByName( key ) ) + return; + Reference< XChangesBatch > xBatch( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + Reference< XNameContainer > xContainer( xBatch, UNO_QUERY ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::removePropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::removePropertySet - " + "No conteiner!" ); + + if ( xBatch.is() && xContainer.is() ) + { + try + { + // Remove item. + xContainer->removeByName( key ); + // Commit changes. + xBatch->commitChanges(); + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::removePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::removePropertySet - " + "caught WrappedTargetException!" ); + return; + } + } + + return; + } + + OSL_ENSURE( sal_False, "PropertySetRegistry::removePropertySet - Error!" ); +} + +//========================================================================= +// +// XElementAccess methods. +// +//========================================================================= + +// virtual +com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType() + throw( RuntimeException ) +{ + return getCppuType( ( Reference< XPersistentPropertySet > * ) 0 ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetRegistry::hasElements() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XElementAccess > xElemAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xElemAccess.is() ) + return xElemAccess->hasElements(); + + return sal_False; +} + +//========================================================================= +// +// XNameAccess methods. +// +//========================================================================= + +// virtual +Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName ) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + + try + { + return xNameAccess->getByName( aName ); + } + catch ( NoSuchElementException& ) + { + // getByName + } + catch ( WrappedTargetException& ) + { + // getByName + } + } + + return Any(); +} + +//========================================================================= +// virtual +Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + return xNameAccess->getElementNames(); + } + return Sequence< OUString >( 0 ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName ) + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + return xNameAccess->hasByName( aName ); + } + + return sal_False; +} + +//========================================================================= +void PropertySetRegistry::add( PersistentPropertySet* pSet ) +{ + OUString key( pSet->getKey() ); + + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + m_pImpl->m_aPropSets[ key ] = pSet; + } +} + +//========================================================================= +void PropertySetRegistry::remove( PersistentPropertySet* pSet ) +{ + OUString key( pSet->getKey() ); + + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; + + PropertySetMap_Impl::iterator it = rSets.find( key ); + if ( it != rSets.end() ) + { + // Found. + rSets.erase( it ); + } + } +} + +//========================================================================= +void PropertySetRegistry::renamePropertySet( const OUString& rOldKey, + const OUString& rNewKey ) +{ + if ( rOldKey == rNewKey ) + return; + + Reference< XNameAccess > xRootNameAccess( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Old key present? + if ( xRootNameAccess->hasByName( rOldKey ) ) + { + // New key not present? + if ( xRootNameAccess->hasByName( rNewKey ) ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "New key exists!" ); + return; + } + Reference< XSingleServiceFactory > xFac( + xRootNameAccess, UNO_QUERY ); + Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PropertySetRegistry::renamePropertySet - " + "No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::renamePropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::renamePropertySet - " + "No container!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + ////////////////////////////////////////////////////// + // Create new "Properties" config item. + ////////////////////////////////////////////////////// + + try + { + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Insert new item. + xContainer->insertByName( + rNewKey, makeAny( xNameReplace ) ); + // Commit changes. + xBatch->commitChanges(); + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught RuntimeException!" ); + return; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught Exception!" ); + return; + } + + ////////////////////////////////////////////////////// + // Copy data... + ////////////////////////////////////////////////////// + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + xRootNameAccess, UNO_QUERY ); + if ( !xRootHierNameAccess.is() ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "No hierarchical name access!" ); + return; + } + + try + { + rtl::OUString aOldValuesKey + = makeHierarchalNameSegment( rOldKey ); + aOldValuesKey += OUString::createFromAscii( "/Values" ); + + Reference< XNameAccess > xOldNameAccess; + xRootHierNameAccess->getByHierarchicalName( + aOldValuesKey ) + >>= xOldNameAccess; + if ( !xOldNameAccess.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No old name access!" ); + return; + } + + // Obtain property names. + Sequence< OUString > aElems + = xOldNameAccess->getElementNames(); + sal_Int32 nCount = aElems.getLength(); + if ( nCount ) + { + rtl::OUString aNewValuesKey + = makeHierarchalNameSegment( rNewKey ); + aNewValuesKey += OUString::createFromAscii( "/Values" ); + + Reference< XSingleServiceFactory > xNewFac; + xRootHierNameAccess->getByHierarchicalName( + aNewValuesKey ) + >>= xNewFac; + if ( !xNewFac.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new factory!" ); + return; + } + + Reference< XNameContainer > xNewContainer( + xNewFac, UNO_QUERY ); + if ( !xNewContainer.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new container!" ); + return; + } + + aOldValuesKey += OUString::createFromAscii( "/" ); + + OUString aHandleKey + = OUString::createFromAscii( "/Handle" ); + OUString aValueKey + = OUString::createFromAscii( "/Value" ); + OUString aStateKey + = OUString::createFromAscii( "/State" ); + OUString aAttrKey + = OUString::createFromAscii( "/Attributes" ); + + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const OUString& rPropName = aElems[ n ]; + + // Create new item. + Reference< XNameReplace > xNewPropNameReplace( + xNewFac->createInstance(), UNO_QUERY ); + + if ( !xNewPropNameReplace.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new prop name replace!" ); + return; + } + + // Fill new item... + + // Set Values + OUString aKey = aOldValuesKey; + aKey += makeHierarchalNameSegment( rPropName ); + + // ... handle + OUString aNewKey1 = aKey; + aNewKey1 += aHandleKey; + Any aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + aAny ); + + // ... value + aNewKey1 = aKey; + aNewKey1 += aValueKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + aAny ); + + // ... state + aNewKey1 = aKey; + aNewKey1 += aStateKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + aAny ); + + // ... attributes + aNewKey1 = aKey; + aNewKey1 += aAttrKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Attributes" ), + aAny ); + + // Insert new item. + xNewContainer->insertByName( + rPropName, makeAny( xNewPropNameReplace ) ); + + // Commit changes. + xBatch->commitChanges(); + } + } + } + catch ( IllegalArgumentException& ) + { + // insertByName, replaceByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // insertByName, replaceByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught RuntimeException!" ); + return; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught Exception!" ); + return; + } + + ////////////////////////////////////////////////////// + // Remove old entry... + ////////////////////////////////////////////////////// + + try + { + // Remove item. + xContainer->removeByName( rOldKey ); + // Commit changes. + xBatch->commitChanges(); + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + } + } + } + + OSL_ENSURE( sal_False, "PropertySetRegistry::renamePropertySet - Error!" ); +} + +//========================================================================= +Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider() +{ + if ( !m_pImpl->m_xConfigProvider.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_xConfigProvider.is() ) + { + const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs; + + if ( rInitArgs.getLength() > 0 ) + { + // Extract config provider from service init args. + rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider; + + OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), + "PropertySetRegistry::getConfigProvider - " + "No config provider!" ); + } + else + { + try + { + m_pImpl->m_xConfigProvider + = Reference< XMultiServiceFactory >( + m_xSMgr->createInstance( + OUString::createFromAscii( + "com.sun.star.configuration." + "ConfigurationProvider" ) ), + UNO_QUERY ); + + OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), + "PropertySetRegistry::getConfigProvider - " + "No config provider!" ); + + } + catch ( Exception& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigProvider - " + "caught exception!" ); + } + } + } + } + + return m_pImpl->m_xConfigProvider; +} + +//========================================================================= +Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess() +{ + try + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + if ( !m_pImpl->m_xRootReadAccess.is() ) + { + if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494# + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - " + "Unable to read any config data! -> #82494#" ); + return Reference< XInterface >(); + } + + getConfigProvider(); + + if ( m_pImpl->m_xConfigProvider.is() ) + { + Sequence< Any > aArguments( 1 ); + PropertyValue aProperty; + aProperty.Name + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_NODEPATH ) ); + aProperty.Value + <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + STORE_CONTENTPROPERTIES_KEY ) ); + aArguments[ 0 ] <<= aProperty; + + m_pImpl->m_bTriedToGetRootReadAccess = sal_True; + + m_pImpl->m_xRootReadAccess = + m_pImpl->m_xConfigProvider->createInstanceWithArguments( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess" ), + aArguments ); + + if ( m_pImpl->m_xRootReadAccess.is() ) + return m_pImpl->m_xRootReadAccess; + } + } + else + return m_pImpl->m_xRootReadAccess; + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + // createInstance, createInstanceWithArguments + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" ); + return Reference< XInterface >(); + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - Error!" ); + return Reference< XInterface >(); +} + +//========================================================================= +Reference< XInterface > PropertySetRegistry::getConfigWriteAccess( + const OUString& rPath ) +{ + try + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + if ( !m_pImpl->m_xRootWriteAccess.is() ) + { + if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494# + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "Unable to write any config data! -> #82494#" ); + return Reference< XInterface >(); + } + + getConfigProvider(); + + if ( m_pImpl->m_xConfigProvider.is() ) + { + Sequence< Any > aArguments( 2 ); + PropertyValue aProperty; + + aProperty.Name + = OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_NODEPATH ) ); + aProperty.Value + <<= OUString( RTL_CONSTASCII_USTRINGPARAM( + STORE_CONTENTPROPERTIES_KEY ) ); + aArguments[ 0 ] <<= aProperty; + + aProperty.Name + = OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_LAZYWRITE ) ); + aProperty.Value <<= sal_True; + aArguments[ 1 ] <<= aProperty; + + m_pImpl->m_bTriedToGetRootWriteAccess = sal_True; + + m_pImpl->m_xRootWriteAccess = + m_pImpl->m_xConfigProvider->createInstanceWithArguments( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationUpdateAccess" ), + aArguments ); + + OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(), + "PropertySetRegistry::getConfigWriteAccess - " + "No config update access!" ); + } + } + + if ( m_pImpl->m_xRootWriteAccess.is() ) + { + if ( rPath.getLength() ) + { + Reference< XHierarchicalNameAccess > xNA( + m_pImpl->m_xRootWriteAccess, UNO_QUERY ); + if ( xNA.is() ) + { + Reference< XInterface > xInterface; + xNA->getByHierarchicalName( rPath ) >>= xInterface; + + if ( xInterface.is() ) + return xInterface; + } + } + else + return m_pImpl->m_xRootWriteAccess; + } + } + catch ( RuntimeException& ) + { + throw; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "caught NoSuchElementException!" ); + return Reference< XInterface >(); + } + catch ( Exception& ) + { + // createInstance, createInstanceWithArguments + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "caught Exception!" ); + return Reference< XInterface >(); + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - Error!" ); + return Reference< XInterface >(); +} + +//========================================================================= +// +// PropertyListeners_Impl. +// +//========================================================================= + +typedef OMultiTypeInterfaceContainerHelperVar +< + OUString, + hashString_Impl, + equalString_Impl +> PropertyListeners_Impl; + +//========================================================================= +// +// PersistentPropertySet_Impl. +// +//========================================================================= + +struct PersistentPropertySet_Impl +{ + PropertySetRegistry* m_pCreator; + PropertySetInfo_Impl* m_pInfo; + OUString m_aKey; + OUString m_aFullKey; + osl::Mutex m_aMutex; + OInterfaceContainerHelper* m_pDisposeEventListeners; + OInterfaceContainerHelper* m_pPropSetChangeListeners; + PropertyListeners_Impl* m_pPropertyChangeListeners; + + PersistentPropertySet_Impl( PropertySetRegistry& rCreator, + const OUString& rKey ) + : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ), + m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ), + m_pPropertyChangeListeners( NULL ) + { + m_pCreator->acquire(); + } + + ~PersistentPropertySet_Impl() + { + m_pCreator->release(); + + if ( m_pInfo ) + m_pInfo->release(); + + delete m_pDisposeEventListeners; + delete m_pPropSetChangeListeners; + delete m_pPropertyChangeListeners; + } +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// PersistentPropertySet Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +PersistentPropertySet::PersistentPropertySet( + const Reference< XMultiServiceFactory >& rXSMgr, + PropertySetRegistry& rCreator, + const OUString& rKey ) +: m_xSMgr( rXSMgr ), + m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) ) +{ + // register at creator. + rCreator.add( this ); +} + +//========================================================================= +// virtual +PersistentPropertySet::~PersistentPropertySet() +{ + // deregister at creator. + m_pImpl->m_pCreator->remove( this ); + + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_9( PersistentPropertySet, + XTypeProvider, + XServiceInfo, + XComponent, + XPropertySet, /* base of XPersistentPropertySet */ + XNamed, + XPersistentPropertySet, + XPropertyContainer, + XPropertySetInfoChangeNotifier, + XPropertyAccess ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_8( PersistentPropertySet, + XTypeProvider, + XServiceInfo, + XComponent, + XPersistentPropertySet, + XNamed, + XPropertyContainer, + XPropertySetInfoChangeNotifier, + XPropertyAccess ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet, + OUString::createFromAscii( + "com.sun.star.comp.ucb.PersistentPropertySet" ), + OUString::createFromAscii( + PERS_PROPSET_SERVICE_NAME ) ); + +//========================================================================= +// +// XComponent methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::dispose() + throw( RuntimeException ) +{ + if ( m_pImpl->m_pDisposeEventListeners && + m_pImpl->m_pDisposeEventListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = static_cast< XComponent * >( this ); + m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this ); + m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt ); + } + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySet * >( this ); + m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt ); + } +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addEventListener( + const Reference< XEventListener >& Listener ) + throw( RuntimeException ) +{ + if ( !m_pImpl->m_pDisposeEventListeners ) + m_pImpl->m_pDisposeEventListeners = + new OInterfaceContainerHelper( m_pImpl->m_aMutex ); + + m_pImpl->m_pDisposeEventListeners->addInterface( Listener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeEventListener( + const Reference< XEventListener >& Listener ) + throw( RuntimeException ) +{ + if ( m_pImpl->m_pDisposeEventListeners ) + m_pImpl->m_pDisposeEventListeners->removeInterface( Listener ); + + // Note: Don't want to delete empty container here -> performance. +} + +//========================================================================= +// +// XPropertySet methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetInfo > SAL_CALL + PersistentPropertySet::getPropertySetInfo() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo; + if ( !rpInfo ) + { + rpInfo = new PropertySetInfo_Impl( m_xSMgr, this ); + rpInfo->acquire(); + } + return Reference< XPropertySetInfo >( rpInfo ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setPropertyValue( + const OUString& aPropertyName, const Any& aValue ) + throw( UnknownPropertyException, + PropertyVetoException, + IllegalArgumentException, + WrappedTargetException, + RuntimeException ) +{ + if ( !aPropertyName.getLength() ) + throw UnknownPropertyException(); + + osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( aPropertyName ); + + // Does property exist? + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + Reference< XNameReplace > xNameReplace( + m_pImpl->m_pCreator->getConfigWriteAccess( + aFullPropName ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( + OUString() ), UNO_QUERY ); + + if ( xNameReplace.is() && xBatch.is() ) + { + try + { + // Obtain old value + OUString aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Value" ); + Any aOldValue + = xRootHierNameAccess->getByHierarchicalName( + aValueName ); + // Check value type. + if ( aOldValue.getValueType() != aValue.getValueType() ) + { + aCGuard.clear(); + throw IllegalArgumentException(); + } + + // Write value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + aValue ); + + // Write state ( Now it is a directly set value ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DIRECT_VALUE ) ) ); + + // Commit changes. + xBatch->commitChanges(); + + PropertyChangeEvent aEvt; + if ( m_pImpl->m_pPropertyChangeListeners ) + { + // Obtain handle + aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Handle" ); + sal_Int32 nHandle = -1; + xRootHierNameAccess->getByHierarchicalName( aValueName ) + >>= nHandle; + + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aPropertyName; + aEvt.PropertyHandle = nHandle; + aEvt.Further = sal_False; + aEvt.OldValue = aOldValue; + aEvt.NewValue = aValue; + + // Callback follows! + aCGuard.clear(); + + notifyPropertyChangeEvent( aEvt ); + } + return; + } + catch ( IllegalArgumentException& ) + { + // replaceByName + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + } + catch ( WrappedTargetException& ) + { + // replaceByName, commitChanges + } + } + } + } + + throw UnknownPropertyException(); +} + +//========================================================================= +// virtual +Any SAL_CALL PersistentPropertySet::getPropertyValue( + const OUString& PropertyName ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ + if ( !PropertyName.getLength() ) + throw UnknownPropertyException(); + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + OUString aFullPropName( getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( PropertyName ); + aFullPropName += OUString::createFromAscii( "/Value" ); + try + { + return xNameAccess->getByHierarchicalName( aFullPropName ); + } + catch ( NoSuchElementException& ) + { + throw UnknownPropertyException(); + } + } + + throw UnknownPropertyException(); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addPropertyChangeListener( + const OUString& aPropertyName, + const Reference< XPropertyChangeListener >& xListener ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); + + if ( !m_pImpl->m_pPropertyChangeListeners ) + m_pImpl->m_pPropertyChangeListeners = + new PropertyListeners_Impl( m_pImpl->m_aMutex ); + + m_pImpl->m_pPropertyChangeListeners->addInterface( + aPropertyName, xListener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removePropertyChangeListener( + const OUString& aPropertyName, + const Reference< XPropertyChangeListener >& aListener ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + m_pImpl->m_pPropertyChangeListeners->removeInterface( + aPropertyName, aListener ); + + // Note: Don't want to delete empty container here -> performance. +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); +// OSL_ENSURE( sal_False, +// "PersistentPropertySet::addVetoableChangeListener - N.Y.I." ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); +// OSL_ENSURE( sal_False, +// "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." ); +} + +//========================================================================= +// +// XPersistentPropertySet methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry() + throw( RuntimeException ) +{ + return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator ); +} + +//========================================================================= +// virtual +OUString SAL_CALL PersistentPropertySet::getKey() + throw( RuntimeException ) +{ + return m_pImpl->m_aKey; +} + +//========================================================================= +// +// XNamed methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL PersistentPropertySet::getName() + throw( RuntimeException ) +{ + // same as getKey() + return m_pImpl->m_aKey; +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setName( const OUString& aName ) + throw( RuntimeException ) +{ + if ( aName != m_pImpl->m_aKey ) + m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName ); +} + +//========================================================================= +// +// XPropertyContainer methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::addProperty( + const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue ) + throw( PropertyExistException, + IllegalTypeException, + IllegalArgumentException, + RuntimeException ) +{ + if ( !Name.getLength() ) + throw IllegalArgumentException(); + + // @@@ What other types can't be written to config server? + + // Check type class ( Not all types can be written to storage ) + TypeClass eTypeClass = DefaultValue.getValueTypeClass(); + if ( eTypeClass == TypeClass_INTERFACE ) + throw IllegalTypeException(); + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + // Property already in set? + + OUString aFullValuesName; + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + aFullValuesName = getFullKey(); + OUString aFullPropName = aFullValuesName; + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + // Already in set. + throw PropertyExistException(); + } + } + + // Property is always removeable. + Attributes |= PropertyAttribute::REMOVEABLE; + + // Add property. + + Reference< XSingleServiceFactory > xFac( + m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), + UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), + UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PersistentPropertySet::addProperty - No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PersistentPropertySet::addProperty - No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PersistentPropertySet::addProperty - No container!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + try + { + // Create new "PropertyValue" config item. + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Fill new item... + + // Set handle + xNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + makeAny( sal_Int32( -1 ) ) ); + + // Set default value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + DefaultValue ); + + // Set state ( always "default" ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DEFAULT_VALUE ) ) ); + + // Set attributes + xNameReplace->replaceByName( + OUString::createFromAscii( "Attributes" ), + makeAny( sal_Int32( Attributes ) ) ); + + // Insert new item. + xContainer->insertByName( Name, makeAny( xNameReplace ) ); + + // Commit changes. + xBatch->commitChanges(); + + // Property set info is invalid. + if ( m_pImpl->m_pInfo ) + m_pImpl->m_pInfo->reset(); + + // Notify propertyset info change listeners. + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + PropertySetInfoChangeEvent evt( + static_cast< OWeakObject * >( this ), + Name, + -1, + PropertySetInfoChange::PROPERTY_INSERTED ); + notifyPropertySetInfoChange( evt ); + } + + // Success. + return; + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // replaceByName, insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught WrappedTargetException!" ); + return; + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught Exception!" ); + return; + } + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - Error!" ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name ) + throw( UnknownPropertyException, + NotRemoveableException, + RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + OUString aFullValuesName; + OUString aFullPropName; + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + aFullValuesName = getFullKey(); + aFullPropName = aFullValuesName; + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + // Property in set? + if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + throw UnknownPropertyException(); + + // Property removeable? + try + { + OUString aFullAttrName = aFullPropName; + aFullAttrName += OUString::createFromAscii( "/Attributes" ); + + sal_Int32 nAttribs = 0; + if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName ) + >>= nAttribs ) + { + if ( !( nAttribs & PropertyAttribute::REMOVEABLE ) ) + { + // Not removeable! + throw NotRemoveableException(); + } + } + else + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "No attributes!" ); + return; + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + } + + // Remove property... + + Reference< XNameContainer > xContainer( + m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), + UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), + UNO_QUERY ); + + OSL_ENSURE( xBatch.is(), + "PersistentPropertySet::removeProperty - No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PersistentPropertySet::removeProperty - No container!" ); + + if ( xBatch.is() && xContainer.is() ) + { + try + { + sal_Int32 nHandle = -1; + + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + // Obtain property handle ( needed for propertysetinfo + // change event )... + + try + { + OUString aFullHandleName = aFullPropName; + aFullHandleName + += OUString::createFromAscii( "/Handle" ); + + if ( ! ( xRootHierNameAccess->getByHierarchicalName( + aFullHandleName ) >>= nHandle ) ) + nHandle = -1; + + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + nHandle = -1; + } + } + + xContainer->removeByName( Name ); + xBatch->commitChanges(); + + // Property set info is invalid. + if ( m_pImpl->m_pInfo ) + m_pImpl->m_pInfo->reset(); + + // Notify propertyset info change listeners. + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + PropertySetInfoChangeEvent evt( + static_cast< OWeakObject * >( this ), + Name, + nHandle, + PropertySetInfoChange::PROPERTY_REMOVED ); + notifyPropertySetInfoChange( evt ); + } + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught WrappedTargetException!" ); + return; + } + } + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - Error!" ); +} + +//========================================================================= +// +// XPropertySetInfoChangeNotifier methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener( + const Reference< XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + if ( !m_pImpl->m_pPropSetChangeListeners ) + m_pImpl->m_pPropSetChangeListeners = + new OInterfaceContainerHelper( m_pImpl->m_aMutex ); + + m_pImpl->m_pPropSetChangeListeners->addInterface( Listener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener( + const Reference< XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + if ( m_pImpl->m_pPropSetChangeListeners ) + m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener ); +} + +//========================================================================= +// +// XPropertyAccess methods. +// +//========================================================================= + +// virtual +Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + try + { + Reference< XNameAccess > xNameAccess; + xRootHierNameAccess->getByHierarchicalName(getFullKey()) + >>= xNameAccess; + if ( xNameAccess.is() ) + { + // Obtain property names. + + Sequence< OUString > aElems = xNameAccess->getElementNames(); + + sal_Int32 nCount = aElems.getLength(); + if ( nCount ) + { + Reference< XHierarchicalNameAccess > xHierNameAccess( + xNameAccess, UNO_QUERY ); + + OSL_ENSURE( xHierNameAccess.is(), + "PersistentPropertySet::getPropertyValues - " + "No hierarchical name access!" ); + + if ( xHierNameAccess.is() ) + { + Sequence< PropertyValue > aValues( nCount ); + + const OUString aHandleName + = OUString::createFromAscii( "/Handle" ); + const OUString aValueName + = OUString::createFromAscii( "/Value" ); + const OUString aStateName + = OUString::createFromAscii( "/State" ); + + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + PropertyValue& rValue = aValues[ n ]; + OUString rName = aElems[ n ]; + OUString aXMLName + = makeHierarchalNameSegment( rName ); + + // Set property name. + + rValue.Name = rName; + + try + { + // Obtain and set property handle + OUString aHierName = aXMLName; + aHierName += aHandleName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + if ( !( aKeyValue >>= rValue.Handle ) ) + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "Error getting property handle!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property value + OUString aHierName = aXMLName; + aHierName += aValueName; + rValue.Value + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + // Note: The value may be void if addProperty + // was called with a default value + // of type void. + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property state + OUString aHierName = aXMLName; + aHierName += aStateName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + sal_Int32 nState = 0; + if ( !( aKeyValue >>= nState ) ) + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "Error getting property state!" ); + else + rValue.State = PropertyState( nState ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + } + + return aValues; + } + } + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + } + } + + return Sequence< PropertyValue >( 0 ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setPropertyValues( + const Sequence< PropertyValue >& aProps ) + throw( UnknownPropertyException, + PropertyVetoException, + IllegalArgumentException, + WrappedTargetException, + RuntimeException ) +{ + sal_Int32 nCount = aProps.getLength(); + if ( !nCount ) + return; + + osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + const PropertyValue* pNewValues = aProps.getConstArray(); + + typedef std::list< PropertyChangeEvent > Events; + Events aEvents; + + OUString aFullPropNamePrefix( getFullKey() ); + aFullPropNamePrefix += OUString::createFromAscii( "/" ); + + // Iterate over given property value sequence. + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const PropertyValue& rNewValue = pNewValues[ n ]; + const OUString& rName = rNewValue.Name; + + OUString aFullPropName = aFullPropNamePrefix; + aFullPropName += makeHierarchalNameSegment( rName ); + + // Does property exist? + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + Reference< XNameReplace > xNameReplace( + m_pImpl->m_pCreator->getConfigWriteAccess( + aFullPropName ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( + OUString() ), UNO_QUERY ); + + if ( xNameReplace.is() && xBatch.is() ) + { + try + { + // Write handle + xNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + makeAny( rNewValue.Handle ) ); + + // Save old value + OUString aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Value" ); + Any aOldValue + = xRootHierNameAccess->getByHierarchicalName( + aValueName ); + // Write value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + rNewValue.Value ); + + // Write state ( Now it is a directly set value ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DIRECT_VALUE ) ) ); + + // Commit changes. + xBatch->commitChanges(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = rNewValue.Name; + aEvt.PropertyHandle = rNewValue.Handle; + aEvt.Further = sal_False; + aEvt.OldValue = aOldValue; + aEvt.NewValue = rNewValue.Value; + + aEvents.push_back( aEvt ); + } + } + catch ( IllegalArgumentException& ) + { + // replaceByName + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + } + catch ( WrappedTargetException& ) + { + // replaceByName, commitChanges + } + } + } + } + + // Callback follows! + aCGuard.clear(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + // Notify property changes. + Events::const_iterator it = aEvents.begin(); + Events::const_iterator end = aEvents.end(); + + while ( it != end ) + { + notifyPropertyChangeEvent( (*it) ); + it++; + } + } + + return; + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::setPropertyValues - Nothing set!" ); +} + +//========================================================================= +// +// Non-interface methods +// +//========================================================================= + +void PersistentPropertySet::notifyPropertyChangeEvent( + const PropertyChangeEvent& rEvent ) const +{ + // Get "normal" listeners for the property. + OInterfaceContainerHelper* pContainer = + m_pImpl->m_pPropertyChangeListeners->getContainer( + rEvent.PropertyName ); + if ( pContainer && pContainer->getLength() ) + { + OInterfaceIteratorHelper aIter( *pContainer ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertyChangeListener > xListener( + aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertyChange( rEvent ); + } + } + + // Get "normal" listeners for all properties. + OInterfaceContainerHelper* pNoNameContainer = + m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() ); + if ( pNoNameContainer && pNoNameContainer->getLength() ) + { + OInterfaceIteratorHelper aIter( *pNoNameContainer ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertyChangeListener > xListener( + aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertyChange( rEvent ); + } + } +} + +//========================================================================= +void PersistentPropertySet::notifyPropertySetInfoChange( + const PropertySetInfoChangeEvent& evt ) const +{ + if ( !m_pImpl->m_pPropSetChangeListeners ) + return; + + // Notify event listeners. + OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertySetInfoChangeListener > + xListener( aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertySetInfoChange( evt ); + } +} + +//========================================================================= +const OUString& PersistentPropertySet::getFullKey() +{ + if ( !m_pImpl->m_aFullKey.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_aFullKey.getLength() ) + { + m_pImpl->m_aFullKey + = makeHierarchalNameSegment( m_pImpl->m_aKey ); + m_pImpl->m_aFullKey + += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Values" ) ); + } + } + + return m_pImpl->m_aFullKey; +} + +//========================================================================= +PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry() +{ + return *m_pImpl->m_pCreator; +} + +//========================================================================= +//========================================================================= +// +// PropertySetInfo_Impl Implementation. +// +//========================================================================= +//========================================================================= + +PropertySetInfo_Impl::PropertySetInfo_Impl( + const Reference< XMultiServiceFactory >& rxSMgr, + PersistentPropertySet* pOwner ) +: m_xSMgr( rxSMgr ), + m_pProps( NULL ), + m_pOwner( pOwner ) +{ +} + +//========================================================================= +// virtual +PropertySetInfo_Impl::~PropertySetInfo_Impl() +{ + delete m_pProps; + + // !!! Do not delete m_pOwner !!! +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_2( PropertySetInfo_Impl, + XTypeProvider, + XPropertySetInfo ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl, + XTypeProvider, + XPropertySetInfo ); + +//========================================================================= +// +// XPropertySetInfo methods. +// +//========================================================================= + +// virtual +Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties() + throw( RuntimeException ) +{ + if ( !m_pProps ) + { + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + try + { + Reference< XNameAccess > xNameAccess; + xRootHierNameAccess->getByHierarchicalName( + m_pOwner->getFullKey() ) + >>= xNameAccess; + if ( xNameAccess.is() ) + { + // Obtain property names. + + Sequence< OUString > aElems + = xNameAccess->getElementNames(); + + sal_uInt32 nCount = aElems.getLength(); + Sequence< Property >* pPropSeq + = new Sequence< Property >( nCount ); + + if ( nCount ) + { + Reference< XHierarchicalNameAccess > xHierNameAccess( + xNameAccess, UNO_QUERY ); + + OSL_ENSURE( xHierNameAccess.is(), + "PropertySetInfo_Impl::getProperties - " + "No hierarchical name access!" ); + + if ( xHierNameAccess.is() ) + { + const OUString aHandleName + = OUString::createFromAscii( "/Handle" ); + const OUString aValueName + = OUString::createFromAscii( "/Value" ); + const OUString aAttrName + = OUString::createFromAscii( "/Attributes" ); + + Property* pProps = pPropSeq->getArray(); + + for ( sal_uInt32 n = 0; n < nCount; ++n ) + { + Property& rProp = pProps[ n ]; + OUString rName = aElems[ n ]; + OUString aXMLName + = makeHierarchalNameSegment( rName ); + + // Set property name. + + rProp.Name = rName; + + try + { + // Obtain and set property handle + rtl::OUString aHierName = aXMLName; + aHierName += aHandleName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + if ( !( aKeyValue >>= rProp.Handle ) ) + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "Error getting property handle!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property type + rtl::OUString aHierName = aXMLName; + aHierName += aValueName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + // Note: The type may be void if addProperty + // was called with a default value + // of type void. + + rProp.Type = aKeyValue.getValueType(); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property attributes + rtl::OUString aHierName = aXMLName; + aHierName += aAttrName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + sal_Int32 nAttribs = 0; + if ( aKeyValue >>= nAttribs ) + rProp.Attributes + = sal_Int16( nAttribs ); + else + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "Error getting property attributes!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + } + } + } + + // Success. + m_pProps = pPropSeq; + return *m_pProps; + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + } + } + + OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getProperties - Error!" ); + m_pProps = new Sequence< Property >( 0 ); + } + + return *m_pProps; +} + +//========================================================================= +// virtual +Property SAL_CALL PropertySetInfo_Impl::getPropertyByName( + const OUString& aName ) + throw( UnknownPropertyException, RuntimeException ) +{ + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( m_pOwner->getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( aName ); + + // Does property exist? + if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + throw UnknownPropertyException(); + + try + { + Property aProp; + + // Obtain handle. + OUString aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Handle" ); + + if ( !( xRootHierNameAccess->getByHierarchicalName( aKey ) + >>= aProp.Handle ) ) + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No handle!" ); + return Property(); + } + + // Obtain Value and extract type. + aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Value" ); + + Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey ); + if ( !aValue.hasValue() ) + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No Value!" ); + return Property(); + } + + aProp.Type = aValue.getValueType(); + + // Obtain Attributes. + aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Attributes" ); + + sal_Int32 nAttribs = 0; + if ( xRootHierNameAccess->getByHierarchicalName( aKey ) + >>= nAttribs ) + aProp.Attributes = sal_Int16( nAttribs ); + else + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No attributes!" ); + return Property(); + } + + // set name. + aProp.Name = aName; + + // Success. + return aProp; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "caught NoSuchElementException!" ); + } + + } + + OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getPropertyByName - Error!" ); + return Property(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName( + const OUString& Name ) + throw( RuntimeException ) +{ + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( m_pOwner->getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + return xRootHierNameAccess->hasByHierarchicalName( aFullPropName ); + } + + return sal_False; +} + diff --git a/ucb/source/core/ucbstore.hxx b/ucb/source/core/ucbstore.hxx new file mode 100644 index 000000000000..7a7a76cb1b99 --- /dev/null +++ b/ucb/source/core/ucbstore.hxx @@ -0,0 +1,345 @@ +/************************************************************************* + * + * 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 _UCBSTORE_HXX +#define _UCBSTORE_HXX + +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp> +#include <com/sun/star/ucb/XPropertySetRegistry.hpp> +#include <com/sun/star/ucb/XPersistentPropertySet.hpp> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/XPropertySetInfoChangeNotifier.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> + +//========================================================================= + +#define STORE_SERVICE_NAME "com.sun.star.ucb.Store" +#define PROPSET_REG_SERVICE_NAME "com.sun.star.ucb.PropertySetRegistry" +#define PERS_PROPSET_SERVICE_NAME "com.sun.star.ucb.PersistentPropertySet" + +//========================================================================= + +struct UcbStore_Impl; + +class UcbStore : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::ucb::XPropertySetRegistryFactory, + public com::sun::star::lang::XInitialization +{ + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > m_xSMgr; + UcbStore_Impl* m_pImpl; + +public: + UcbStore( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rXSMgr ); + virtual ~UcbStore(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_DECL() + + // XPropertySetRegistryFactory + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XPropertySetRegistry > SAL_CALL + createPropertySetRegistry( const rtl::OUString& URL ) + throw( 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 ); + + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& + getInitArgs() const; +}; + +//========================================================================= + +struct PropertySetRegistry_Impl; +class PersistentPropertySet; + +class PropertySetRegistry : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::ucb::XPropertySetRegistry, + public com::sun::star::container::XNameAccess +{ + friend class PersistentPropertySet; + + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > m_xSMgr; + PropertySetRegistry_Impl* m_pImpl; + +private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > + getConfigProvider(); + + void add ( PersistentPropertySet* pSet ); + void remove( PersistentPropertySet* pSet ); + + void renamePropertySet( const rtl::OUString& rOldKey, + const rtl::OUString& rNewKey ); + +public: + PropertySetRegistry( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rXSMgr, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Any >& rInitArgs); + virtual ~PropertySetRegistry(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_NOFACTORY_DECL() + + // XPropertySetRegistry + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XPersistentPropertySet > SAL_CALL + openPropertySet( const rtl::OUString& key, sal_Bool create ) + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removePropertySet( const rtl::OUString& key ) + throw( com::sun::star::uno::RuntimeException ); + + // XElementAccess ( XNameAccess is derived from it ) + virtual com::sun::star::uno::Type SAL_CALL + getElementType() + throw( com::sun::star::uno::RuntimeException ); + virtual sal_Bool SAL_CALL + hasElements() + throw( com::sun::star::uno::RuntimeException ); + + // XNameAccess + virtual com::sun::star::uno::Any SAL_CALL + getByName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getElementNames() + throw( com::sun::star::uno::RuntimeException ); + virtual sal_Bool SAL_CALL + hasByName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ); + + // Non-interface methods + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > + getRootConfigReadAccess(); + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > + getConfigWriteAccess( const rtl::OUString& rPath ); +}; + +//========================================================================= + +struct PersistentPropertySet_Impl; + +class PersistentPropertySet : + public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::lang::XComponent, + public com::sun::star::ucb::XPersistentPropertySet, + public com::sun::star::container::XNamed, + public com::sun::star::beans::XPropertyContainer, + public com::sun::star::beans::XPropertySetInfoChangeNotifier, + public com::sun::star::beans::XPropertyAccess +{ + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > m_xSMgr; + PersistentPropertySet_Impl* m_pImpl; + +private: + void notifyPropertyChangeEvent( + const com::sun::star::beans::PropertyChangeEvent& rEvent ) const; + void notifyPropertySetInfoChange( + const com::sun::star::beans::PropertySetInfoChangeEvent& evt ) const; + +public: + PersistentPropertySet( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rXSMgr, + PropertySetRegistry& rCreator, + const rtl::OUString& rKey ); + virtual ~PersistentPropertySet(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_NOFACTORY_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 >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< + com::sun::star::lang::XEventListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + // XPropertySet + virtual com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + setPropertyValue( const rtl::OUString& aPropertyName, + const com::sun::star::uno::Any& aValue ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual com::sun::star::uno::Any SAL_CALL + getPropertyValue( const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + addPropertyChangeListener( const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removePropertyChangeListener( const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + addVetoableChangeListener( const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< + com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removeVetoableChangeListener( const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< + com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + // XPersistentPropertySet + virtual com::sun::star::uno::Reference< + com::sun::star::ucb::XPropertySetRegistry > SAL_CALL + getRegistry() + throw( com::sun::star::uno::RuntimeException ); + virtual rtl::OUString SAL_CALL + getKey() + throw( com::sun::star::uno::RuntimeException ); + + // XNamed + virtual rtl::OUString SAL_CALL + getName() + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + setName( const ::rtl::OUString& aName ) + throw( ::com::sun::star::uno::RuntimeException ); + + // XPropertyContainer + virtual void SAL_CALL + addProperty( const rtl::OUString& Name, + sal_Int16 Attributes, + const com::sun::star::uno::Any& DefaultValue ) + throw( com::sun::star::beans::PropertyExistException, + com::sun::star::beans::IllegalTypeException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removeProperty( const rtl::OUString& Name ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::NotRemoveableException, + com::sun::star::uno::RuntimeException ); + + // XPropertySetInfoChangeNotifier + virtual void SAL_CALL + addPropertySetInfoChangeListener( const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySetInfoChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + removePropertySetInfoChangeListener( const com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySetInfoChangeListener >& Listener ) + throw( com::sun::star::uno::RuntimeException ); + + // XPropertyAccess + virtual com::sun::star::uno::Sequence< + com::sun::star::beans::PropertyValue > SAL_CALL + getPropertyValues() + throw( com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL + setPropertyValues( const com::sun::star::uno::Sequence< + com::sun::star::beans::PropertyValue >& aProps ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException ); + + // Non-interface methods. + PropertySetRegistry& getPropertySetRegistry(); + const rtl::OUString& getFullKey(); +}; + +#endif /* !_UCBSTORE_HXX */ |