update dev300-m58
[ooovba.git] / comphelper / inc / comphelper / servicedecl.hxx
blobca9375ab4bde19bdebffe58a7120f43bcb6679fa
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servicedecl.hxx,v $
10 * $Revision: 1.6 $
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"
35 #endif
36 #if ! defined(_CPPUHELPER_IMPLBASE1_HXX_)
37 #include "cppuhelper/implbase1.hxx"
38 #endif
39 #if ! defined(_COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_)
40 #include "com/sun/star/uno/XComponentContext.hpp"
41 #endif
42 #if ! defined(_COM_SUN_STAR_LANG_XSERVICEINFO_HPP_)
43 #include "com/sun/star/lang/XServiceInfo.hpp"
44 #endif
45 #if ! defined(_COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_)
46 #include "com/sun/star/registry/XRegistryKey.hpp"
47 #endif
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 {
57 class ServiceDecl;
59 namespace detail {
60 namespace css = ::com::sun::star;
61 typedef ::boost::function3<
62 css::uno::Reference<css::uno::XInterface> /* return */,
63 ServiceDecl const&,
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
72 <pre>
73 class MyClass : cppu::WeakImplHelper2<XInterface1, XInterface2> {
74 public:
75 MyClass( uno::Reference<uno::XComponentContext> const& xContext )
76 [...]
78 [...]
79 namespace sdecl = comphelper::service_decl;
80 sdecl::ServiceDecl const myDecl(
81 sdecl::class_<MyClass>(),
82 "my.unique.implementation.name",
83 "MyServiceSpec1;MyServiceSpec2" );
84 </pre>
86 If the service demands initialization by arguments, the implementation
87 class has to define a constructor taking both arguments and component
88 context:
90 <pre>
91 class MyClass : cppu::WeakImplHelper2<XInterface1, XInterface2> {
92 public:
93 MyClass( uno::Sequence<uno::Any> const& args,
94 uno::Reference<uno:XComponentContext> const& xContext )
95 [...]
97 [...]
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" );
103 </pre>
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
107 (C++-UNO only):
109 <pre>
110 uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
111 [...]
112 namespace sdecl = comphelper::service_decl;
113 sdecl::ServiceDecl const myDecl(
114 sdecl::class_<MyClass, ... >(&somePostProcCode),
115 "my.unique.implementation.name",
116 "MyServiceSpec1;MyServiceSpec2" );
117 </pre>
119 In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
121 class COMPHELPER_DLLPUBLIC ServiceDecl : private ::boost::noncopyable
123 public:
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),
138 m_cDelim(cDelim) {}
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;
155 private:
156 class Factory;
157 friend class Factory;
159 detail::CreateFuncF const m_createFunc;
160 char const* const m_pImplName;
161 char const* const m_pServiceNames;
162 char const m_cDelim;
165 /** To specify whether the implementation class expects arguments
166 (uno::Sequence<uno::Any>).
168 template <bool> struct with_args;
170 /// @internal
171 namespace detail {
172 template <typename ImplT>
173 class OwnServiceImpl
174 : public ImplT,
175 private ::boost::noncopyable
177 typedef ImplT BaseT;
179 public:
180 OwnServiceImpl(
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) {}
185 OwnServiceImpl(
186 ServiceDecl const& rServiceDecl,
187 css::uno::Reference<css::uno::XComponentContext> const& xContext )
188 : BaseT(xContext), m_rServiceDecl(rServiceDecl) {}
190 // XServiceInfo
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();
204 private:
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;
212 public:
213 ServiceImpl(
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) {}
218 ServiceImpl(
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>
233 struct CreateFunc;
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_) \
333 if (pRet == 0) \
334 pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName);
336 /** The following preprocessor repetitions generate functions like
338 <pre>
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, ... );
349 </pre>
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) ) \
362 bool bRet = true; \
363 BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_writeInfo, ~) \
364 return bRet; \
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) ) \
372 void * pRet = 0; \
373 BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \
374 return pRet; \
377 #if ! defined(COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS)
378 #define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8
379 #endif
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:
400 <pre>
401 // must reside outside _any_ namespace
402 COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1,
403 yourServiceDecl2,
404 yourServiceDecl3);
405 </pre>
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:
411 <pre>
412 // must reside outside _any_ namespace
413 COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN));
414 </pre>
416 Note the missing colons between the bracketed arguments.
418 #define COMPHELPER_SERVICEDECL_make_exports(varargs_ ) \
419 extern "C" \
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, \
439 pRegistryKey, \
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)