Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / include / comphelper / servicedecl.hxx
blob5fece98d9e251717c93c796cc7a7a47f58d106fd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
28 #include <functional>
29 #include <initializer_list>
31 namespace comphelper {
32 namespace service_decl {
34 class ServiceDecl;
36 namespace detail {
37 typedef ::std::function<
38 css::uno::Reference<css::uno::XInterface> /* return */
39 (ServiceDecl const&,
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
48 <pre>
49 class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> {
50 public:
51 MyClass( uno::Reference<uno::XComponentContext> const& xContext )
52 [...]
54 [...]
55 namespace sdecl = comphelper::service_decl;
56 sdecl::ServiceDecl const myDecl(
57 sdecl::class_<MyClass>(),
58 "my.unique.implementation.name",
59 "MyServiceSpec1;MyServiceSpec2" );
60 </pre>
62 If the service demands initialization by arguments, the implementation
63 class has to define a constructor taking both arguments and component
64 context:
66 <pre>
67 class MyClass : public cppu::WeakImplHelper<XInterface1, XInterface2> {
68 public:
69 MyClass( uno::Sequence<uno::Any> const& args,
70 uno::Reference<uno:XComponentContext> const& xContext )
71 [...]
73 [...]
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" );
79 </pre>
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
83 (C++-UNO only):
85 <pre>
86 uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
87 [...]
88 namespace sdecl = comphelper::service_decl;
89 sdecl::ServiceDecl const myDecl(
90 sdecl::class_<MyClass, ... >(&somePostProcCode),
91 "my.unique.implementation.name",
92 "MyServiceSpec1;MyServiceSpec2" );
93 </pre>
95 In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
97 class COMPHELPER_DLLPUBLIC ServiceDecl
99 public:
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),
116 m_cDelim(cDelim) {}
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;
130 private:
131 class Factory;
132 friend class Factory;
134 detail::CreateFuncF const m_createFunc;
135 char const* const m_pImplName;
136 char const* const m_pServiceNames;
137 char const m_cDelim;
140 /** To specify whether the implementation class expects arguments
141 (uno::Sequence<uno::Any>).
143 template <bool> struct with_args;
145 /// @internal
146 namespace detail {
147 template <typename ImplT>
148 class OwnServiceImpl
149 : public ImplT
151 typedef ImplT BaseT;
153 public:
154 OwnServiceImpl( const OwnServiceImpl& ) = delete;
155 OwnServiceImpl& operator=( const OwnServiceImpl& ) = delete;
156 OwnServiceImpl(
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) {}
161 OwnServiceImpl(
162 ServiceDecl const& rServiceDecl,
163 css::uno::Reference<css::uno::XComponentContext> const& xContext )
164 : BaseT(xContext), m_rServiceDecl(rServiceDecl) {}
166 // XServiceInfo
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();
180 private:
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;
188 public:
189 ServiceImpl(
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) {}
194 ServiceImpl(
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;
204 public:
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>
221 struct CreateFunc;
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 ) {}
332 COMPHELPER_DLLPUBLIC
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: */