54d6e9f7dc
Change-Id: I58d2020035396da0b3580b058d87c8e2d3f2df40 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133750 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
269 lines
10 KiB
C++
269 lines
10 KiB
C++
/* -*- 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 .
|
|
*/
|
|
|
|
#ifndef INCLUDED_UNOTOOLS_SHAREDUNOCOMPONENT_HXX
|
|
#define INCLUDED_UNOTOOLS_SHAREDUNOCOMPONENT_HXX
|
|
|
|
#include <unotools/unotoolsdllapi.h>
|
|
#include <com/sun/star/uno/Reference.hxx>
|
|
#include <rtl/ref.hxx>
|
|
#include <memory>
|
|
|
|
namespace com::sun::star {
|
|
namespace lang {
|
|
class XComponent;
|
|
}
|
|
}
|
|
|
|
namespace utl
|
|
{
|
|
|
|
//= DisposableComponent
|
|
|
|
/** is a class which controls lifetime of a UNO component via ->XComponent::dispose
|
|
|
|
You'll usually never use this class directly, but only as parameter for a
|
|
->SharedUNOComponent class.
|
|
*/
|
|
class UNOTOOLS_DLLPUBLIC DisposableComponent
|
|
{
|
|
css::uno::Reference< css::lang::XComponent > m_xComponent;
|
|
|
|
public:
|
|
/** constructs a ->DisposableComponent instance
|
|
|
|
@param _rxComponent
|
|
the component whose life time should be controlled by the instance. Must not be <NULL/>.
|
|
*/
|
|
DisposableComponent( const css::uno::Reference< css::uno::XInterface >& _rxComponent );
|
|
|
|
/** disposes the component represented by the instance
|
|
|
|
The component is queried for ->XComponent(which <em>must</em> be supported),
|
|
and ->XComponent::dispose is invoked. A failure of this invocation (e.g. a thrown
|
|
exception) is silenced in release builds, and reported in debug builds.
|
|
*/
|
|
~DisposableComponent();
|
|
|
|
private:
|
|
DisposableComponent( const DisposableComponent& ) = delete;
|
|
DisposableComponent& operator=( const DisposableComponent& ) = delete;
|
|
};
|
|
|
|
//= CloseableComponent
|
|
|
|
class CloseableComponentImpl;
|
|
/** is a class which controls lifetime of a UNO component via ->XCloseable::close
|
|
|
|
You'll usually never use this class directly, but only as parameter for a
|
|
->SharedUNOComponent class.
|
|
*/
|
|
class UNOTOOLS_DLLPUBLIC CloseableComponent
|
|
{
|
|
private:
|
|
/** Our IMPL class.
|
|
*/
|
|
::rtl::Reference< CloseableComponentImpl > m_pImpl;
|
|
|
|
public:
|
|
/** constructs a ->CloseableComponent instance
|
|
|
|
@param _rxComponent
|
|
the component whose life time should be controlled by the instance. Must not be <NULL/>.
|
|
*/
|
|
CloseableComponent( const css::uno::Reference< css::uno::XInterface >& _rxComponent );
|
|
|
|
/** destroys resources associated with this instance, and disposes the component
|
|
|
|
The component is queried for ->XCloseable (which <em>must</em> be supported),
|
|
and ->XCloseable::close is invoked, with delivering the ownership.
|
|
If the invocation fails with a ->CloseVetoException, this is ignored, since in
|
|
this case the vetoing instance took the ownership.
|
|
|
|
Any other failure will be reported in a debug version via assertion mechanisms,
|
|
and silenced in release builds.
|
|
*/
|
|
~CloseableComponent();
|
|
|
|
private:
|
|
CloseableComponent( const CloseableComponent& ) = delete;
|
|
CloseableComponent& operator=( const CloseableComponent& ) = delete;
|
|
};
|
|
|
|
//= SharedUNOComponent
|
|
|
|
/** is a helper class for sharing ownership of a UNO component
|
|
|
|
If you need to share a UNO component, which normally needs a dedicated owner,
|
|
and is lifetime controlled by an explicit disposal action (not necessarily ->XComponent::dispose,
|
|
but <em>any</em> explicit method call, after which the object is considered
|
|
to be disposed), between different classes, ->SharedUNOComponent is what you need.
|
|
|
|
Instead of passing around a <code>Reference< XFoo ></code>, and bothering
|
|
with ownership and disposal, you just use a <code>SharedUNOComponent< XFoo ></code>.
|
|
This instance can be passed around, including copying, and in nearly all respects behaves
|
|
like the original <code>Reference< XFoo ></code>. However, when the last
|
|
->SharedUNOComponent referencing a certain <code>Reference< XFoo ></code> dies, it
|
|
will automatically get rid of the object held by this reference.
|
|
|
|
@param INTERFACE
|
|
the UNO interface type as which the component should be held
|
|
|
|
@param COMPONENT_HOLDER
|
|
a class which can be used to represent and dispose a UNO component.
|
|
The class must support (maybe explicit only) construction from a
|
|
<code>Reference< INTERFACE ></code>, and destruction. Upon destruction,
|
|
the class must dispose (by any suitable means) the component instance it was
|
|
constructed with.
|
|
*/
|
|
template < class INTERFACE, class COMPONENT = DisposableComponent >
|
|
class SharedUNOComponent
|
|
{
|
|
private:
|
|
typedef COMPONENT Component;
|
|
|
|
private:
|
|
std::shared_ptr<Component> m_xComponent;
|
|
css::uno::Reference< INTERFACE > m_xTypedComponent;
|
|
|
|
public:
|
|
enum AssignmentMode
|
|
{
|
|
TakeOwnership,
|
|
NoTakeOwnership
|
|
};
|
|
|
|
public:
|
|
SharedUNOComponent()
|
|
{
|
|
}
|
|
|
|
explicit SharedUNOComponent( const css::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode eMode = TakeOwnership )
|
|
{
|
|
reset( _rxComponent, eMode );
|
|
}
|
|
|
|
SharedUNOComponent( const css::uno::BaseReference & _rRef, css::uno::UnoReference_QueryThrow _queryThrow )
|
|
{
|
|
set( _rRef, _queryThrow );
|
|
}
|
|
|
|
// SharedUNOComponent& operator=( const css::uno::Reference< INTERFACE >& _rxComponent );
|
|
// This operator is intentionally not implemented. There is no canonic ownership after this operator
|
|
// would have been applied: Should the SharedUNOComponent have the ownership of the component,
|
|
// or shouldn't it? Hard to guess, and probably wrong in 50 percent of all cases, anyway. So,
|
|
// instead of tempting clients of this class to use such a dangerous operator, we do
|
|
// not offer it at all. If you need to assign a Reference< INTERFACE > to your SharedUNOComponent,
|
|
// use the ->reset method.
|
|
|
|
/** assigns a new component, and releases the old one
|
|
*/
|
|
void reset( const css::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode _eMode = TakeOwnership );
|
|
|
|
inline bool set( const css::uno::BaseReference& _rRef, css::uno::UnoReference_Query _query );
|
|
|
|
inline void set( const css::uno::BaseReference & _rRef, css::uno::UnoReference_QueryThrow _queryThrow );
|
|
|
|
inline void set( const css::uno::Reference< INTERFACE >& _rRef, css::uno::UnoReference_SetThrow _setThrow );
|
|
inline void set( const SharedUNOComponent& _rComp, css::uno::UnoReference_SetThrow _setThrow );
|
|
|
|
INTERFACE* SAL_CALL operator->() const;
|
|
|
|
operator const css::uno::Reference< INTERFACE >&() const
|
|
{
|
|
return m_xTypedComponent;
|
|
}
|
|
|
|
const css::uno::Reference< INTERFACE >& getTyped() const
|
|
{
|
|
return m_xTypedComponent;
|
|
}
|
|
|
|
bool is() const
|
|
{
|
|
return m_xTypedComponent.is();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
m_xComponent.reset();
|
|
m_xTypedComponent.clear();
|
|
}
|
|
};
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
INTERFACE* SAL_CALL SharedUNOComponent< INTERFACE, COMPONENT >::operator->() const
|
|
{
|
|
return m_xTypedComponent.operator->();
|
|
}
|
|
|
|
// assignments
|
|
template < class INTERFACE, class COMPONENT >
|
|
void SharedUNOComponent< INTERFACE, COMPONENT >::reset( const css::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode _eMode )
|
|
{
|
|
m_xComponent.reset(_eMode == TakeOwnership ? new COMPONENT( _rxComponent ) : nullptr);
|
|
m_xTypedComponent = _rxComponent;
|
|
}
|
|
|
|
// comparison operators
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
bool operator==( const SharedUNOComponent< INTERFACE, COMPONENT >& _rLHS, const css::uno::Reference< INTERFACE >& _rRHS )
|
|
{
|
|
return _rLHS.getTyped() == _rRHS;
|
|
}
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
inline css::uno::Any SAL_CALL makeAny( const SharedUNOComponent< INTERFACE, COMPONENT >& value )
|
|
{
|
|
return css::uno::Any( value.getTyped() );
|
|
}
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
void SharedUNOComponent< INTERFACE, COMPONENT >::set( const css::uno::BaseReference & _rRef, css::uno::UnoReference_QueryThrow _queryThrow )
|
|
{
|
|
reset( css::uno::Reference< INTERFACE >( _rRef, _queryThrow ), TakeOwnership );
|
|
}
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
void SharedUNOComponent< INTERFACE, COMPONENT >::set( const css::uno::Reference< INTERFACE >& _rRef, css::uno::UnoReference_SetThrow _setThrow )
|
|
{
|
|
reset( css::uno::Reference< INTERFACE >( _rRef, _setThrow ), TakeOwnership );
|
|
}
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
void SharedUNOComponent< INTERFACE, COMPONENT >::set( const SharedUNOComponent& _rComp, css::uno::UnoReference_SetThrow _setThrow )
|
|
{
|
|
*this = _rComp;
|
|
// provoke an exception in case the component is NULL
|
|
m_xTypedComponent.set( m_xTypedComponent, _setThrow );
|
|
}
|
|
|
|
template < class INTERFACE, class COMPONENT >
|
|
bool SharedUNOComponent< INTERFACE, COMPONENT >::set( const css::uno::BaseReference& _rRef, css::uno::UnoReference_Query _query )
|
|
{
|
|
reset( css::uno::Reference< INTERFACE >( _rRef, _query ) );
|
|
return is();
|
|
}
|
|
|
|
} // namespace utl
|
|
|
|
#endif // INCLUDED_UNOTOOLS_SHAREDUNOCOMPONENT_HXX
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|