1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_COMPHELPER_SERVICEDECL_HXX
20 #define INCLUDED_COMPHELPER_SERVICEDECL_HXX
22 #include <comphelper/comphelperdllapi.h>
23 #include <cppuhelper/implbase.hxx>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <com/sun/star/lang/XServiceInfo.hpp>
26 #include <uno/environment.h>
29 #include <initializer_list>
31 namespace comphelper
{
32 namespace service_decl
{
37 typedef ::std::function
<
38 css::uno::Reference
<css::uno::XInterface
> /* return */
40 css::uno::Sequence
<css::uno::Any
> const&,
41 css::uno::Reference
<css::uno::XComponentContext
> const&)> CreateFuncF
;
44 /** Class to declare a service implementation. There is no need to implement
45 lang::XServiceInfo nor lang::XInitialization anymore.
46 The declaration can be done in various ways, the (simplest) form is
49 class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> {
51 MyClass( uno::Reference<uno::XComponentContext> const& xContext )
55 namespace sdecl = comphelper::service_decl;
56 sdecl::ServiceDecl const myDecl(
57 sdecl::class_<MyClass>(),
58 "my.unique.implementation.name",
59 "MyServiceSpec1;MyServiceSpec2" );
62 If the service demands initialization by arguments, the implementation
63 class has to define a constructor taking both arguments and component
67 class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> {
69 MyClass( uno::Sequence<uno::Any> const& args,
70 uno::Reference<uno:XComponentContext> const& xContext )
74 namespace sdecl = comphelper::service_decl;
75 sdecl::ServiceDecl const myDecl(
76 sdecl::class_<MyClass, sdecl::with_args<true> >(),
77 "my.unique.implementation.name",
78 "MyServiceSpec1;MyServiceSpec2" );
81 Additionally, there is the possibility to process some code after creation,
82 e.g. to add the newly created object as a listener or perform aggregation
86 uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
88 namespace sdecl = comphelper::service_decl;
89 sdecl::ServiceDecl const myDecl(
90 sdecl::class_<MyClass, ... >(&somePostProcCode),
91 "my.unique.implementation.name",
92 "MyServiceSpec1;MyServiceSpec2" );
95 In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
97 class COMPHELPER_DLLPUBLIC ServiceDecl
100 /** Ctor for multiple supported service names.
102 @param implClass implementation class description
103 @param pImplName implementation name
104 @param pSupportedServiceNames supported service names
105 @param cDelim delimiter for supported service names
107 ServiceDecl( const ServiceDecl
& ) = delete;
108 ServiceDecl
& operator=( const ServiceDecl
& ) = delete;
109 template <typename ImplClassT
>
110 ServiceDecl( ImplClassT
const& implClass
,
111 char const* pImplName
,
112 char const* pSupportedServiceNames
, char cDelim
= ';' )
113 : m_createFunc(implClass
.m_createFunc
),
114 m_pImplName(pImplName
),
115 m_pServiceNames(pSupportedServiceNames
),
118 /// @internal gets called by component_getFactoryHelper()
119 void * getFactory( sal_Char
const* pImplName
) const;
121 /// @return supported service names
122 css::uno::Sequence
< OUString
> getSupportedServiceNames() const;
124 /// @return whether name is in set of supported service names
125 bool supportsService( OUString
const& name
) const;
127 /// @return implementation name
128 OUString
getImplementationName() const;
132 friend class Factory
;
134 detail::CreateFuncF
const m_createFunc
;
135 char const* const m_pImplName
;
136 char const* const m_pServiceNames
;
140 /** To specify whether the implementation class expects arguments
141 (uno::Sequence<uno::Any>).
143 template <bool> struct with_args
;
147 template <typename ImplT
>
154 OwnServiceImpl( const OwnServiceImpl
& ) = delete;
155 OwnServiceImpl
& operator=( const OwnServiceImpl
& ) = delete;
157 ServiceDecl
const& rServiceDecl
,
158 css::uno::Sequence
<css::uno::Any
> const& args
,
159 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
160 :BaseT(args
, xContext
), m_rServiceDecl(rServiceDecl
) {}
162 ServiceDecl
const& rServiceDecl
,
163 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
164 : BaseT(xContext
), m_rServiceDecl(rServiceDecl
) {}
167 virtual OUString SAL_CALL
getImplementationName()
168 throw (css::uno::RuntimeException
) override
{
169 return m_rServiceDecl
.getImplementationName();
171 virtual sal_Bool SAL_CALL
supportsService( OUString
const& name
)
172 throw (css::uno::RuntimeException
) override
{
173 return m_rServiceDecl
.supportsService(name
);
175 virtual css::uno::Sequence
< OUString
>
176 SAL_CALL
getSupportedServiceNames() throw (css::uno::RuntimeException
) override
{
177 return m_rServiceDecl
.getSupportedServiceNames();
181 ServiceDecl
const& m_rServiceDecl
;
184 template <typename ImplT
>
185 class ServiceImpl
: public OwnServiceImpl
< ::cppu::ImplInheritanceHelper
<ImplT
,css::lang::XServiceInfo
> >
187 typedef OwnServiceImpl
< ::cppu::ImplInheritanceHelper
<ImplT
,css::lang::XServiceInfo
> > ServiceImpl_BASE
;
190 ServiceDecl
const& rServiceDecl
,
191 css::uno::Sequence
<css::uno::Any
> const& args
,
192 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
193 : ServiceImpl_BASE(rServiceDecl
, args
, xContext
) {}
195 ServiceDecl
const& rServiceDecl
,
196 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
197 : ServiceImpl_BASE(rServiceDecl
, xContext
) {}
200 template <typename ImplT
>
201 class InheritingServiceImpl
: public OwnServiceImpl
< ImplT
>
203 typedef OwnServiceImpl
< ImplT
> ServiceImpl_BASE
;
205 InheritingServiceImpl(
206 ServiceDecl
const& rServiceDecl
,
207 css::uno::Sequence
<css::uno::Any
> const& args
,
208 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
209 : ServiceImpl_BASE(rServiceDecl
, args
, xContext
) {}
212 template <typename ServiceImplT
>
213 struct PostProcessDefault
{
214 css::uno::Reference
<css::uno::XInterface
>
215 operator()( ServiceImplT
* p
) const {
216 return static_cast<css::lang::XServiceInfo
*>(p
);
220 template <typename ImplT
, typename PostProcessFuncT
, typename WithArgsT
>
223 template <typename ImplT
, typename PostProcessFuncT
>
224 struct CreateFunc
<ImplT
, PostProcessFuncT
, with_args
<false> > {
225 PostProcessFuncT
const m_postProcessFunc
;
226 explicit CreateFunc( PostProcessFuncT
const& postProcessFunc
)
227 : m_postProcessFunc(postProcessFunc
) {}
229 css::uno::Reference
<css::uno::XInterface
>
230 operator()( ServiceDecl
const& rServiceDecl
,
231 css::uno::Sequence
<css::uno::Any
> const&,
232 css::uno::Reference
<css::uno::XComponentContext
>
233 const& xContext
) const
235 return m_postProcessFunc(
236 new ImplT( rServiceDecl
, xContext
) );
240 template <typename ImplT
, typename PostProcessFuncT
>
241 struct CreateFunc
<ImplT
, PostProcessFuncT
, with_args
<true> > {
242 PostProcessFuncT
const m_postProcessFunc
;
243 explicit CreateFunc( PostProcessFuncT
const& postProcessFunc
)
244 : m_postProcessFunc(postProcessFunc
) {}
246 css::uno::Reference
<css::uno::XInterface
>
247 operator()( ServiceDecl
const& rServiceDecl
,
248 css::uno::Sequence
<css::uno::Any
> const& args
,
249 css::uno::Reference
<css::uno::XComponentContext
>
250 const& xContext
) const
252 return m_postProcessFunc(
253 new ImplT( rServiceDecl
, args
, xContext
) );
257 } // namespace detail
259 /** Defines a service implementation class.
261 @tpl ImplT_ service implementation class
262 @WithArgsT whether the implementation class ctor expects arguments
263 (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>)
264 or just (uno::Reference<uno::XComponentContext>)
266 template <typename ImplT_
, typename WithArgsT
= with_args
<false> >
267 struct serviceimpl_base
{
268 typedef ImplT_ ImplT
;
270 detail::CreateFuncF
const m_createFunc
;
272 typedef detail::PostProcessDefault
<ImplT
> PostProcessDefaultT
;
274 /** Default ctor. Implementation class without args, expecting
275 component context as single argument.
277 serviceimpl_base() : m_createFunc(
278 detail::CreateFunc
<ImplT
, PostProcessDefaultT
, WithArgsT
>(
279 PostProcessDefaultT() ) ) {}
281 /** Ctor to pass a post processing function/functor.
283 @tpl PostProcessDefaultT let your compiler deduce this
284 @param postProcessFunc function/functor that gets the yet unacquired
285 ImplT_ pointer returning a
286 uno::Reference<uno::XInterface>
288 template <typename PostProcessFuncT
>
289 explicit serviceimpl_base( PostProcessFuncT
const& postProcessFunc
)
290 : m_createFunc( detail::CreateFunc
<ImplT
, PostProcessFuncT
, WithArgsT
>(
291 postProcessFunc
) ) {}
294 template <typename ImplT_
, typename WithArgsT
= with_args
<false> >
295 struct class_
: public serviceimpl_base
< detail::ServiceImpl
<ImplT_
>, WithArgsT
>
297 typedef serviceimpl_base
< detail::ServiceImpl
<ImplT_
>, WithArgsT
> baseT
;
298 /** Default ctor. Implementation class without args, expecting
299 component context as single argument.
301 class_() : baseT() {}
302 template <typename PostProcessFuncT
>
303 /** Ctor to pass a post processing function/functor.
305 @tpl PostProcessDefaultT let your compiler deduce this
306 @param postProcessFunc function/functor that gets the yet unacquired
307 ImplT_ pointer returning a
308 uno::Reference<uno::XInterface>
310 explicit class_( PostProcessFuncT
const& postProcessFunc
) : baseT( postProcessFunc
) {}
313 template <typename ImplT_
, typename WithArgsT
= with_args
<false> >
314 struct inheritingClass_
: public serviceimpl_base
< detail::InheritingServiceImpl
<ImplT_
>, WithArgsT
>
316 typedef serviceimpl_base
< detail::InheritingServiceImpl
<ImplT_
>, WithArgsT
> baseT
;
317 /** Default ctor. Implementation class without args, expecting
318 component context as single argument.
320 inheritingClass_() : baseT() {}
321 template <typename PostProcessFuncT
>
322 /** Ctor to pass a post processing function/functor.
324 @tpl PostProcessDefaultT let your compiler deduce this
325 @param postProcessFunc function/functor that gets the yet unacquired
326 ImplT_ pointer returning a
327 uno::Reference<uno::XInterface>
329 explicit inheritingClass_( PostProcessFuncT
const& postProcessFunc
) : baseT( postProcessFunc
) {}
333 void* component_getFactoryHelper( const sal_Char
* pImplName
,
334 std::initializer_list
<ServiceDecl
const *> args
);
336 } // namespace service_decl
337 } // namespace comphelper
340 #endif // ! defined( INCLUDED_COMPHELPER_SERVICEDECL_HXX)
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */