1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servicedecl.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #if ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED)
31 #define COMPHELPER_SERVICEDECL_HXX_INCLUDED
33 #if ! defined(INCLUDED_COMPHELPERDLLAPI_H)
34 #include "comphelper/comphelperdllapi.h"
36 #if ! defined(_CPPUHELPER_IMPLBASE1_HXX_)
37 #include "cppuhelper/implbase1.hxx"
39 #if ! defined(_COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_)
40 #include "com/sun/star/uno/XComponentContext.hpp"
42 #if ! defined(_COM_SUN_STAR_LANG_XSERVICEINFO_HPP_)
43 #include "com/sun/star/lang/XServiceInfo.hpp"
45 #if ! defined(_COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_)
46 #include "com/sun/star/registry/XRegistryKey.hpp"
48 #include "boost/utility.hpp"
49 #include "boost/function.hpp"
50 #include "boost/preprocessor/cat.hpp"
51 #include "boost/preprocessor/repetition.hpp"
52 #include "boost/preprocessor/seq/enum.hpp"
54 namespace comphelper
{
55 namespace service_decl
{
60 namespace css
= ::com::sun::star
;
61 typedef ::boost::function3
<
62 css::uno::Reference
<css::uno::XInterface
> /* return */,
64 css::uno::Sequence
<css::uno::Any
> const&,
65 css::uno::Reference
<css::uno::XComponentContext
> const&> CreateFuncF
;
68 /** Class to declare a service implementation. There is no need to implement
69 lang::XServiceInfo nor lang::XInitialization anymore.
70 The declaration can be done in various ways, the (simplest) form is
73 class MyClass : cppu::WeakImplHelper2<XInterface1, XInterface2> {
75 MyClass( uno::Reference<uno::XComponentContext> const& xContext )
79 namespace sdecl = comphelper::service_decl;
80 sdecl::ServiceDecl const myDecl(
81 sdecl::class_<MyClass>(),
82 "my.unique.implementation.name",
83 "MyServiceSpec1;MyServiceSpec2" );
86 If the service demands initialization by arguments, the implementation
87 class has to define a constructor taking both arguments and component
91 class MyClass : cppu::WeakImplHelper2<XInterface1, XInterface2> {
93 MyClass( uno::Sequence<uno::Any> const& args,
94 uno::Reference<uno:XComponentContext> const& xContext )
98 namespace sdecl = comphelper::service_decl;
99 sdecl::ServiceDecl const myDecl(
100 sdecl::class_<MyClass, sdecl::with_args<true> >(),
101 "my.unique.implementation.name",
102 "MyServiceSpec1;MyServiceSpec2" );
105 Additionally, there is the possibility to process some code after creation,
106 e.g. to add the newly created object as a listener or perform aggregation
110 uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
112 namespace sdecl = comphelper::service_decl;
113 sdecl::ServiceDecl const myDecl(
114 sdecl::class_<MyClass, ... >(&somePostProcCode),
115 "my.unique.implementation.name",
116 "MyServiceSpec1;MyServiceSpec2" );
119 In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
121 class COMPHELPER_DLLPUBLIC ServiceDecl
: private ::boost::noncopyable
124 /** Ctor for multiple supported service names.
126 @param implClass implementation class description
127 @param pImplName implementation name
128 @param pSupportedServiceNames supported service names
129 @param cDelim delimiter for supported service names
131 template <typename ImplClassT
>
132 ServiceDecl( ImplClassT
const& implClass
,
133 char const* pImplName
,
134 char const* pSupportedServiceNames
, char cDelim
= ';' )
135 : m_createFunc(implClass
.m_createFunc
),
136 m_pImplName(pImplName
),
137 m_pServiceNames(pSupportedServiceNames
),
140 /// @internal gets called by component_writeInfoHelper()
141 bool writeInfo( ::com::sun::star::registry::XRegistryKey
* xKey
) const;
142 /// @internal gets called by component_getFactoryHelper()
143 void * getFactory( sal_Char
const* pImplName
) const;
145 /// @return supported service names
146 ::com::sun::star::uno::Sequence
< ::rtl::OUString
>
147 getSupportedServiceNames() const;
149 /// @return whether name is in set of supported service names
150 bool supportsService( ::rtl::OUString
const& name
) const;
152 /// @return implementation name
153 ::rtl::OUString
getImplementationName() const;
157 friend class Factory
;
159 detail::CreateFuncF
const m_createFunc
;
160 char const* const m_pImplName
;
161 char const* const m_pServiceNames
;
165 /** To specify whether the implementation class expects arguments
166 (uno::Sequence<uno::Any>).
168 template <bool> struct with_args
;
172 template <typename ImplT
>
175 private ::boost::noncopyable
181 ServiceDecl
const& rServiceDecl
,
182 css::uno::Sequence
<css::uno::Any
> const& args
,
183 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
184 : BaseT(args
, xContext
), m_rServiceDecl(rServiceDecl
) {}
186 ServiceDecl
const& rServiceDecl
,
187 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
188 : BaseT(xContext
), m_rServiceDecl(rServiceDecl
) {}
191 virtual ::rtl::OUString SAL_CALL
getImplementationName()
192 throw (css::uno::RuntimeException
) {
193 return m_rServiceDecl
.getImplementationName();
195 virtual sal_Bool SAL_CALL
supportsService( ::rtl::OUString
const& name
)
196 throw (css::uno::RuntimeException
) {
197 return m_rServiceDecl
.supportsService(name
);
199 virtual css::uno::Sequence
< ::rtl::OUString
>
200 SAL_CALL
getSupportedServiceNames() throw (css::uno::RuntimeException
) {
201 return m_rServiceDecl
.getSupportedServiceNames();
205 ServiceDecl
const& m_rServiceDecl
;
208 template <typename ImplT
>
209 class ServiceImpl
: public OwnServiceImpl
< ::cppu::ImplInheritanceHelper1
<ImplT
,css::lang::XServiceInfo
> >
211 typedef OwnServiceImpl
< ::cppu::ImplInheritanceHelper1
<ImplT
,css::lang::XServiceInfo
> > ServiceImpl_BASE
;
214 ServiceDecl
const& rServiceDecl
,
215 css::uno::Sequence
<css::uno::Any
> const& args
,
216 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
217 : ServiceImpl_BASE(rServiceDecl
, args
, xContext
) {}
219 ServiceDecl
const& rServiceDecl
,
220 css::uno::Reference
<css::uno::XComponentContext
> const& xContext
)
221 : ServiceImpl_BASE(rServiceDecl
, xContext
) {}
224 template <typename ServiceImplT
>
225 struct PostProcessDefault
{
226 css::uno::Reference
<css::uno::XInterface
>
227 operator()( ServiceImplT
* p
) const {
228 return static_cast<css::lang::XServiceInfo
*>(p
);
232 template <typename ImplT
, typename PostProcessFuncT
, typename WithArgsT
>
235 template <typename ImplT
, typename PostProcessFuncT
>
236 struct CreateFunc
<ImplT
, PostProcessFuncT
, with_args
<false> > {
237 PostProcessFuncT
const m_postProcessFunc
;
238 explicit CreateFunc( PostProcessFuncT
const& postProcessFunc
)
239 : m_postProcessFunc(postProcessFunc
) {}
241 css::uno::Reference
<css::uno::XInterface
>
242 operator()( ServiceDecl
const& rServiceDecl
,
243 css::uno::Sequence
<css::uno::Any
> const&,
244 css::uno::Reference
<css::uno::XComponentContext
>
245 const& xContext
) const
247 return m_postProcessFunc(
248 new ImplT( rServiceDecl
, xContext
) );
252 template <typename ImplT
, typename PostProcessFuncT
>
253 struct CreateFunc
<ImplT
, PostProcessFuncT
, with_args
<true> > {
254 PostProcessFuncT
const m_postProcessFunc
;
255 explicit CreateFunc( PostProcessFuncT
const& postProcessFunc
)
256 : m_postProcessFunc(postProcessFunc
) {}
258 css::uno::Reference
<css::uno::XInterface
>
259 operator()( ServiceDecl
const& rServiceDecl
,
260 css::uno::Sequence
<css::uno::Any
> const& args
,
261 css::uno::Reference
<css::uno::XComponentContext
>
262 const& xContext
) const
264 return m_postProcessFunc(
265 new ImplT( rServiceDecl
, args
, xContext
) );
269 } // namespace detail
271 /** Defines a service implementation class.
273 @tpl ImplT_ service implementation class
274 @WithArgsT whether the implementation class ctor expects arguments
275 (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>)
276 or just (uno::Reference<uno::XComponentContext>)
278 template <typename ImplT_
, typename WithArgsT
= with_args
<false> >
279 struct serviceimpl_base
{
280 typedef ImplT_ ImplT
;
282 detail::CreateFuncF
const m_createFunc
;
284 typedef detail::PostProcessDefault
<ImplT
> PostProcessDefaultT
;
286 /** Default ctor. Implementation class without args, expecting
287 component context as single argument.
289 serviceimpl_base() : m_createFunc(
290 detail::CreateFunc
<ImplT
, PostProcessDefaultT
, WithArgsT
>(
291 PostProcessDefaultT() ) ) {}
293 /** Ctor to pass a post processing function/functor.
295 @tpl PostProcessDefaultT let your compiler deduce this
296 @param postProcessFunc function/functor that gets the yet unacquired
297 ImplT_ pointer returning a
298 uno::Reference<uno::XInterface>
300 template <typename PostProcessFuncT
>
301 explicit serviceimpl_base( PostProcessFuncT
const& postProcessFunc
)
302 : m_createFunc( detail::CreateFunc
<ImplT
, PostProcessFuncT
, WithArgsT
>(
303 postProcessFunc
) ) {}
306 template <typename ImplT_
, typename WithArgsT
= with_args
<false> >
307 struct class_
: public serviceimpl_base
< detail::ServiceImpl
<ImplT_
>, WithArgsT
>
309 typedef serviceimpl_base
< detail::ServiceImpl
<ImplT_
>, WithArgsT
> baseT
;
310 /** Default ctor. Implementation class without args, expecting
311 component context as single argument.
313 class_() : baseT() {}
314 template <typename PostProcessFuncT
>
315 /** Ctor to pass a post processing function/functor.
317 @tpl PostProcessDefaultT let your compiler deduce this
318 @param postProcessFunc function/functor that gets the yet unacquired
319 ImplT_ pointer returning a
320 uno::Reference<uno::XInterface>
322 explicit class_( PostProcessFuncT
const& postProcessFunc
) : baseT( postProcessFunc
) {}
326 // component_... helpers with arbitrary service declarations:
329 #define COMPHELPER_SERVICEDECL_writeInfo(z_, n_, unused_) \
330 bRet &= BOOST_PP_CAT(s, n_).writeInfo( xRegistryKey );
332 #define COMPHELPER_SERVICEDECL_getFactory(z_, n_, unused_) \
334 pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName);
336 /** The following preprocessor repetitions generate functions like
339 inline sal_Bool component_writeInfoHelper(
340 ::com::sun::star::lang::XMultiServiceFactory *,
341 ::com::sun::star::registry::XRegistryKey * xRegistryKey,
342 ServiceDecl const& s0, ServiceDecl const& s1, ... );
344 inline void * component_getFactoryHelper(
345 sal_Char const* pImplName,
346 ::com::sun::star::lang::XMultiServiceFactory *,
347 ::com::sun::star::registry::XRegistryKey * xRegistryKey,
348 ServiceDecl const& s0, ServiceDecl const& s1, ... );
351 which call on the passed service declarations.
353 The maximum number of service declarations can be set by defining
354 COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS; its default is 8.
356 #define COMPHELPER_SERVICEDECL_make(z_, n_, unused_) \
357 inline sal_Bool component_writeInfoHelper( \
358 ::com::sun::star::lang::XMultiServiceFactory *, \
359 ::com::sun::star::registry::XRegistryKey * xRegistryKey, \
360 BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \
363 BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_writeInfo, ~) \
366 inline void * component_getFactoryHelper( \
367 sal_Char const* pImplName, \
368 ::com::sun::star::lang::XMultiServiceFactory *, \
369 ::com::sun::star::registry::XRegistryKey *, \
370 BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \
373 BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \
377 #if ! defined(COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS)
378 #define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8
381 BOOST_PP_REPEAT_FROM_TO(1, COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS
,
382 COMPHELPER_SERVICEDECL_make
, ~)
384 #undef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS
385 #undef COMPHELPER_SERVICEDECL_make
386 #undef COMPHELPER_SERVICEDECL_getFactory
387 #undef COMPHELPER_SERVICEDECL_writeInfo
389 } // namespace service_decl
390 } // namespace comphelper
392 /** The following preprocessor macro generates the C access functions,
393 that are used to initialize and register the components of a
394 shared library object.
396 If you have, say, written a lib that contains three distinct
397 components, each with its own ServiceDecl object, you might want
398 to employ the following code:
401 // must reside outside _any_ namespace
402 COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1,
407 For your convenience, the COMPHELPER_SERVICEDECL_EXPORTS<N> macro
408 comes pre-defined up to N=8, if you should need more arguments,
409 call COMPHELPER_SERVICEDECL_make_exports directly, like this:
412 // must reside outside _any_ namespace
413 COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN));
416 Note the missing colons between the bracketed arguments.
418 #define COMPHELPER_SERVICEDECL_make_exports(varargs_ ) \
421 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char** ppEnvTypeName, \
422 uno_Environment** /*ppEnv*/ ) \
424 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; \
427 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( ::com::sun::star::lang::XMultiServiceFactory* pServiceManager, \
428 ::com::sun::star::registry::XRegistryKey* pRegistryKey ) \
430 return component_writeInfoHelper( pServiceManager, pRegistryKey, \
431 BOOST_PP_SEQ_ENUM(varargs_) ); \
434 SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( sal_Char const* pImplName, \
435 ::com::sun::star::lang::XMultiServiceFactory* pServiceManager, \
436 ::com::sun::star::registry::XRegistryKey* pRegistryKey ) \
438 return component_getFactoryHelper( pImplName, pServiceManager, \
440 BOOST_PP_SEQ_ENUM(varargs_) ); \
444 #define COMPHELPER_SERVICEDECL_EXPORTS1(comp0_) \
445 COMPHELPER_SERVICEDECL_make_exports((comp0_))
446 #define COMPHELPER_SERVICEDECL_EXPORTS2(comp0_,comp1_) \
447 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_))
448 #define COMPHELPER_SERVICEDECL_EXPORTS3(comp0_,comp1_,comp2_) \
449 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_))
450 #define COMPHELPER_SERVICEDECL_EXPORTS4(comp0_,comp1_,comp2_,comp3_) \
451 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_))
452 #define COMPHELPER_SERVICEDECL_EXPORTS5(comp0_,comp1_,comp2_,comp3_,comp4_) \
453 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_))
454 #define COMPHELPER_SERVICEDECL_EXPORTS6(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_) \
455 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_))
456 #define COMPHELPER_SERVICEDECL_EXPORTS7(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_) \
457 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_))
458 #define COMPHELPER_SERVICEDECL_EXPORTS8(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_,comp7_) \
459 COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)(comp7_))
461 #endif // ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED)