    /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    /*
     * This file is part of the LibreOffice project.
     *
     * This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     *
     * This file incorporates work covered by the following license notice:
     *
     *   Licensed to the Apache Software Foundation (ASF) under one or more
     *   contributor license agreements. See the NOTICE file distributed
     *   with this work for additional information regarding copyright
     *   ownership. The ASF licenses this file to you under the Apache
     *   License, Version 2.0 (the "License"); you may not use this file
     *   except in compliance with the License. You may obtain a copy of
     *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
     */

    #include <osl/diagnose.h>
    #include <osl/thread.h>
    #include <rtl/strbuf.hxx>
    #include <sal/log.hxx>
    #include "provprox.hxx"
    #include <com/sun/star/lang/XInitialization.hpp>
    #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
    #include <cppuhelper/queryinterface.hxx>

    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()
    {
    }

    // XServiceInfo methods.

    XSERVICEINFO_COMMOM_IMPL( UcbContentProviderProxyFactory,
                              OUString( "com.sun.star.comp.ucb.UcbContentProviderProxyFactory" ) )
    /// @throws css::uno::Exception
    static css::uno::Reference< css::uno::XInterface >
    UcbContentProviderProxyFactory_CreateInstance( const css::uno::Reference< css::lang::XMultiServiceFactory> & rSMgr )
    {
        css::lang::XServiceInfo* pX =
            static_cast<css::lang::XServiceInfo*>(new UcbContentProviderProxyFactory( rSMgr ));
        return css::uno::Reference< css::uno::XInterface >::query( pX );
    }
    css::uno::Sequence< OUString >
    UcbContentProviderProxyFactory::getSupportedServiceNames_Static()
    {
        return { "com.sun.star.ucb.ContentProviderProxyFactory" };
    }

    // Service factory implementation.

    ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbContentProviderProxyFactory );

    // XContentProviderFactory methods.

    // virtual
    Reference< XContentProvider > SAL_CALL
    UcbContentProviderProxyFactory::createContentProvider(
                                                    const OUString& Service )
    {
        return Reference< XContentProvider >(
                            new UcbContentProviderProxy( m_xSMgr, Service ) );
    }

    // UcbContentProviderProxy Implementation.

    UcbContentProviderProxy::UcbContentProviderProxy(
                            const Reference< XMultiServiceFactory >& rxSMgr,
                            const OUString& Service )
    : m_aService( Service ),
      m_bReplace( false ),
      m_bRegister( false ),
      m_xSMgr( rxSMgr )
    {
    }

    // virtual
    UcbContentProviderProxy::~UcbContentProviderProxy()
    {
    }

    // XInterface methods.
    void SAL_CALL UcbContentProviderProxy::acquire()
        throw()
    {
        OWeakObject::acquire();
    }

    void SAL_CALL UcbContentProviderProxy::release()
        throw()
    {
        OWeakObject::release();
    }

    // virtual
    Any SAL_CALL
    UcbContentProviderProxy::queryInterface( const Type & rType )
    {
        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()
    {
        // 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 s_aCollection(
                CPPU_TYPE_REF( XTypeProvider ),
                CPPU_TYPE_REF( XServiceInfo ),
                CPPU_TYPE_REF( XContentProvider ),
                CPPU_TYPE_REF( XParameterizedContentProvider ),
                CPPU_TYPE_REF( XContentProviderSupplier ) );
            return s_aCollection.getTypes();
        }
    }

    // XServiceInfo methods.

    OUString SAL_CALL UcbContentProviderProxy::getImplementationName()
    {
        return OUString( "com.sun.star.comp.ucb.UcbContentProviderProxy" );
    }

    sal_Bool SAL_CALL UcbContentProviderProxy::supportsService( const OUString& ServiceName )
    {
        return cppu::supportsService( this, ServiceName );
    }

    css::uno::Sequence< OUString > SAL_CALL UcbContentProviderProxy::getSupportedServiceNames()
    {
        return { "com.sun.star.ucb.ContentProviderProxy" };
    }

    // XContentProvider methods.

    // virtual
    Reference< XContent > SAL_CALL UcbContentProviderProxy::queryContent(
                            const Reference< XContentIdentifier >& Identifier )
    {
        // 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 )
    {
        // 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_FAIL( // "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 )
    {
        // 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  = true;
        }
        return this;
    }

    // virtual
    Reference< XContentProvider > SAL_CALL
    UcbContentProviderProxy::deregisterInstance( const OUString& Template,
                                                 const OUString& Arguments )
    {
        osl::Guard< osl::Mutex > aGuard( m_aMutex );

        // registerInstance called at proxy and at original?
        if ( m_bRegister && m_xTargetProvider.is() )
        {
            m_bRegister       = false;
            m_xTargetProvider = nullptr;

            Reference< XParameterizedContentProvider >
                                    xParamProvider( m_xProvider, UNO_QUERY );
            if ( xParamProvider.is() )
            {
                try
                {
                    xParamProvider->deregisterInstance( Template, Arguments );
                }
                catch ( IllegalIdentifierException const & )
                {
                    OSL_FAIL( "UcbContentProviderProxy::deregisterInstance - "
                        "Caught IllegalIdentifierException!" );
                }
            }
        }

        return this;
    }

    // XContentProviderSupplier methods.

    // virtual
    Reference< XContentProvider > SAL_CALL
    UcbContentProviderProxy::getContentProvider()
    {
        osl::Guard< osl::Mutex > aGuard( m_aMutex );
        if ( !m_xProvider.is() )
        {
            try
            {
                m_xProvider.set( m_xSMgr->createInstance( m_aService ), UNO_QUERY );
                if ( m_aArguments == "NoConfig" )
                {
                    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 & e)
            {
                SAL_INFO( "ucb.core", "Exception when getting content provider: " << e );
            }

            // 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_FAIL( "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(),
            OStringBuffer("UcbContentProviderProxy::getContentProvider - No provider for '").append(OUStringToOString(m_aService, osl_getThreadTextEncoding())).append(".").getStr() );
        return m_xTargetProvider;
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V572 It is odd that the object which was created using 'new' operator is immediately cast to another type.