1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski #if ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED)
24*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_HXX_INCLUDED
25*b1cdbd2cSJim Jagielski 
26*b1cdbd2cSJim Jagielski #include <comphelper/comphelperdllapi.h>
27*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase1.hxx>
28*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/XComponentContext.hpp>
29*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XServiceInfo.hpp>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/registry/XRegistryKey.hpp>
31*b1cdbd2cSJim Jagielski #include <uno/environment.h>
32*b1cdbd2cSJim Jagielski #include <boost/utility.hpp>
33*b1cdbd2cSJim Jagielski #include <boost/function.hpp>
34*b1cdbd2cSJim Jagielski #include <boost/preprocessor/cat.hpp>
35*b1cdbd2cSJim Jagielski #include <boost/preprocessor/repetition.hpp>
36*b1cdbd2cSJim Jagielski #include <boost/preprocessor/seq/enum.hpp>
37*b1cdbd2cSJim Jagielski 
38*b1cdbd2cSJim Jagielski namespace comphelper {
39*b1cdbd2cSJim Jagielski namespace service_decl {
40*b1cdbd2cSJim Jagielski 
41*b1cdbd2cSJim Jagielski class ServiceDecl;
42*b1cdbd2cSJim Jagielski 
43*b1cdbd2cSJim Jagielski namespace detail {
44*b1cdbd2cSJim Jagielski namespace css = ::com::sun::star;
45*b1cdbd2cSJim Jagielski typedef ::boost::function3<
46*b1cdbd2cSJim Jagielski     css::uno::Reference<css::uno::XInterface> /* return */,
47*b1cdbd2cSJim Jagielski     ServiceDecl const&,
48*b1cdbd2cSJim Jagielski     css::uno::Sequence<css::uno::Any> const&,
49*b1cdbd2cSJim Jagielski     css::uno::Reference<css::uno::XComponentContext> const&> CreateFuncF;
50*b1cdbd2cSJim Jagielski }
51*b1cdbd2cSJim Jagielski 
52*b1cdbd2cSJim Jagielski /** Class to declare a service implementation.  There is no need to implement
53*b1cdbd2cSJim Jagielski     lang::XServiceInfo nor lang::XInitialization anymore.
54*b1cdbd2cSJim Jagielski     The declaration can be done in various ways, the (simplest) form is
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski     <pre>
57*b1cdbd2cSJim Jagielski     class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> {
58*b1cdbd2cSJim Jagielski     public:
59*b1cdbd2cSJim Jagielski         MyClass( uno::Reference<uno::XComponentContext> const& xContext )
60*b1cdbd2cSJim Jagielski         [...]
61*b1cdbd2cSJim Jagielski     };
62*b1cdbd2cSJim Jagielski     [...]
63*b1cdbd2cSJim Jagielski     namespace sdecl = comphelper::service_decl;
64*b1cdbd2cSJim Jagielski     sdecl::ServiceDecl const myDecl(
65*b1cdbd2cSJim Jagielski         sdecl::class_<MyClass>(),
66*b1cdbd2cSJim Jagielski         "my.unique.implementation.name",
67*b1cdbd2cSJim Jagielski         "MyServiceSpec1;MyServiceSpec2" );
68*b1cdbd2cSJim Jagielski     </pre>
69*b1cdbd2cSJim Jagielski 
70*b1cdbd2cSJim Jagielski     If the service demands initialization by arguments, the implementation
71*b1cdbd2cSJim Jagielski     class has to define a constructor taking both arguments and component
72*b1cdbd2cSJim Jagielski     context:
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski     <pre>
75*b1cdbd2cSJim Jagielski     class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> {
76*b1cdbd2cSJim Jagielski     public:
77*b1cdbd2cSJim Jagielski         MyClass( uno::Sequence<uno::Any> const& args,
78*b1cdbd2cSJim Jagielski                  uno::Reference<uno:XComponentContext> const& xContext )
79*b1cdbd2cSJim Jagielski         [...]
80*b1cdbd2cSJim Jagielski     };
81*b1cdbd2cSJim Jagielski     [...]
82*b1cdbd2cSJim Jagielski     namespace sdecl = comphelper::service_decl;
83*b1cdbd2cSJim Jagielski     sdecl::ServiceDecl const myDecl(
84*b1cdbd2cSJim Jagielski         sdecl::class_<MyClass, sdecl::with_args<true> >(),
85*b1cdbd2cSJim Jagielski         "my.unique.implementation.name",
86*b1cdbd2cSJim Jagielski         "MyServiceSpec1;MyServiceSpec2" );
87*b1cdbd2cSJim Jagielski     </pre>
88*b1cdbd2cSJim Jagielski 
89*b1cdbd2cSJim Jagielski     Additionally, there is the possibility to process some code after creation,
90*b1cdbd2cSJim Jagielski     e.g. to add the newly created object as a listener or perform aggregation
91*b1cdbd2cSJim Jagielski     (C++-UNO only):
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski     <pre>
94*b1cdbd2cSJim Jagielski     uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
95*b1cdbd2cSJim Jagielski     [...]
96*b1cdbd2cSJim Jagielski     namespace sdecl = comphelper::service_decl;
97*b1cdbd2cSJim Jagielski     sdecl::ServiceDecl const myDecl(
98*b1cdbd2cSJim Jagielski         sdecl::class_<MyClass, ... >(&somePostProcCode),
99*b1cdbd2cSJim Jagielski         "my.unique.implementation.name",
100*b1cdbd2cSJim Jagielski         "MyServiceSpec1;MyServiceSpec2" );
101*b1cdbd2cSJim Jagielski     </pre>
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski     In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
104*b1cdbd2cSJim Jagielski */
105*b1cdbd2cSJim Jagielski class COMPHELPER_DLLPUBLIC ServiceDecl : private ::boost::noncopyable
106*b1cdbd2cSJim Jagielski {
107*b1cdbd2cSJim Jagielski public:
108*b1cdbd2cSJim Jagielski     /** Ctor for multiple supported service names.
109*b1cdbd2cSJim Jagielski 
110*b1cdbd2cSJim Jagielski         @param implClass implementation class description
111*b1cdbd2cSJim Jagielski         @param pImplName implementation name
112*b1cdbd2cSJim Jagielski         @param pSupportedServiceNames supported service names
113*b1cdbd2cSJim Jagielski         @param cDelim delimiter for supported service names
114*b1cdbd2cSJim Jagielski     */
115*b1cdbd2cSJim Jagielski     template <typename ImplClassT>
ServiceDecl(ImplClassT const & implClass,char const * pImplName,char const * pSupportedServiceNames,char cDelim=';')116*b1cdbd2cSJim Jagielski     ServiceDecl( ImplClassT const& implClass,
117*b1cdbd2cSJim Jagielski                  char const* pImplName,
118*b1cdbd2cSJim Jagielski                  char const* pSupportedServiceNames, char cDelim = ';' )
119*b1cdbd2cSJim Jagielski         : m_createFunc(implClass.m_createFunc),
120*b1cdbd2cSJim Jagielski           m_pImplName(pImplName),
121*b1cdbd2cSJim Jagielski           m_pServiceNames(pSupportedServiceNames),
122*b1cdbd2cSJim Jagielski           m_cDelim(cDelim) {}
123*b1cdbd2cSJim Jagielski 
124*b1cdbd2cSJim Jagielski     /// @internal gets called by component_getFactoryHelper()
125*b1cdbd2cSJim Jagielski     void * getFactory( sal_Char const* pImplName ) const;
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski     /// @return supported service names
128*b1cdbd2cSJim Jagielski     ::com::sun::star::uno::Sequence< ::rtl::OUString>
129*b1cdbd2cSJim Jagielski     getSupportedServiceNames() const;
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski     /// @return whether name is in set of supported service names
132*b1cdbd2cSJim Jagielski     bool supportsService( ::rtl::OUString const& name ) const;
133*b1cdbd2cSJim Jagielski 
134*b1cdbd2cSJim Jagielski     /// @return implementation name
135*b1cdbd2cSJim Jagielski     ::rtl::OUString getImplementationName() const;
136*b1cdbd2cSJim Jagielski 
137*b1cdbd2cSJim Jagielski private:
138*b1cdbd2cSJim Jagielski     class Factory;
139*b1cdbd2cSJim Jagielski     friend class Factory;
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski     detail::CreateFuncF const m_createFunc;
142*b1cdbd2cSJim Jagielski     char const* const m_pImplName;
143*b1cdbd2cSJim Jagielski     char const* const m_pServiceNames;
144*b1cdbd2cSJim Jagielski     char const m_cDelim;
145*b1cdbd2cSJim Jagielski };
146*b1cdbd2cSJim Jagielski 
147*b1cdbd2cSJim Jagielski /** To specify whether the implementation class expects arguments
148*b1cdbd2cSJim Jagielski     (uno::Sequence<uno::Any>).
149*b1cdbd2cSJim Jagielski */
150*b1cdbd2cSJim Jagielski template <bool> struct with_args;
151*b1cdbd2cSJim Jagielski 
152*b1cdbd2cSJim Jagielski /// @internal
153*b1cdbd2cSJim Jagielski namespace detail {
154*b1cdbd2cSJim Jagielski template <typename ImplT>
155*b1cdbd2cSJim Jagielski class OwnServiceImpl
156*b1cdbd2cSJim Jagielski     : public ImplT,
157*b1cdbd2cSJim Jagielski       private ::boost::noncopyable
158*b1cdbd2cSJim Jagielski {
159*b1cdbd2cSJim Jagielski     typedef ImplT BaseT;
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski public:
OwnServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Sequence<css::uno::Any> const & args,css::uno::Reference<css::uno::XComponentContext> const & xContext)162*b1cdbd2cSJim Jagielski     OwnServiceImpl(
163*b1cdbd2cSJim Jagielski         ServiceDecl const& rServiceDecl,
164*b1cdbd2cSJim Jagielski         css::uno::Sequence<css::uno::Any> const& args,
165*b1cdbd2cSJim Jagielski         css::uno::Reference<css::uno::XComponentContext> const& xContext )
166*b1cdbd2cSJim Jagielski         :BaseT(args, xContext), m_rServiceDecl(rServiceDecl) {}
OwnServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Reference<css::uno::XComponentContext> const & xContext)167*b1cdbd2cSJim Jagielski     OwnServiceImpl(
168*b1cdbd2cSJim Jagielski         ServiceDecl const& rServiceDecl,
169*b1cdbd2cSJim Jagielski         css::uno::Reference<css::uno::XComponentContext> const& xContext )
170*b1cdbd2cSJim Jagielski         : BaseT(xContext), m_rServiceDecl(rServiceDecl) {}
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski     // XServiceInfo
getImplementationName()173*b1cdbd2cSJim Jagielski     virtual ::rtl::OUString SAL_CALL getImplementationName()
174*b1cdbd2cSJim Jagielski         throw (css::uno::RuntimeException) {
175*b1cdbd2cSJim Jagielski         return m_rServiceDecl.getImplementationName();
176*b1cdbd2cSJim Jagielski     }
supportsService(::rtl::OUString const & name)177*b1cdbd2cSJim Jagielski     virtual sal_Bool SAL_CALL supportsService( ::rtl::OUString const& name )
178*b1cdbd2cSJim Jagielski         throw (css::uno::RuntimeException) {
179*b1cdbd2cSJim Jagielski         return m_rServiceDecl.supportsService(name);
180*b1cdbd2cSJim Jagielski     }
181*b1cdbd2cSJim Jagielski     virtual css::uno::Sequence< ::rtl::OUString>
getSupportedServiceNames()182*b1cdbd2cSJim Jagielski     SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) {
183*b1cdbd2cSJim Jagielski         return m_rServiceDecl.getSupportedServiceNames();
184*b1cdbd2cSJim Jagielski     }
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski private:
187*b1cdbd2cSJim Jagielski     ServiceDecl const& m_rServiceDecl;
188*b1cdbd2cSJim Jagielski };
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski template <typename ImplT>
191*b1cdbd2cSJim Jagielski class ServiceImpl : public OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> >
192*b1cdbd2cSJim Jagielski {
193*b1cdbd2cSJim Jagielski typedef OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > ServiceImpl_BASE;
194*b1cdbd2cSJim Jagielski public:
ServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Sequence<css::uno::Any> const & args,css::uno::Reference<css::uno::XComponentContext> const & xContext)195*b1cdbd2cSJim Jagielski     ServiceImpl(
196*b1cdbd2cSJim Jagielski         ServiceDecl const& rServiceDecl,
197*b1cdbd2cSJim Jagielski         css::uno::Sequence<css::uno::Any> const& args,
198*b1cdbd2cSJim Jagielski         css::uno::Reference<css::uno::XComponentContext> const& xContext )
199*b1cdbd2cSJim Jagielski         : ServiceImpl_BASE(rServiceDecl, args, xContext) {}
ServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Reference<css::uno::XComponentContext> const & xContext)200*b1cdbd2cSJim Jagielski     ServiceImpl(
201*b1cdbd2cSJim Jagielski         ServiceDecl const& rServiceDecl,
202*b1cdbd2cSJim Jagielski         css::uno::Reference<css::uno::XComponentContext> const& xContext )
203*b1cdbd2cSJim Jagielski         : ServiceImpl_BASE(rServiceDecl, xContext) {}
204*b1cdbd2cSJim Jagielski };
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski template <typename ServiceImplT>
207*b1cdbd2cSJim Jagielski struct PostProcessDefault {
208*b1cdbd2cSJim Jagielski     css::uno::Reference<css::uno::XInterface>
operator ()comphelper::service_decl::detail::PostProcessDefault209*b1cdbd2cSJim Jagielski     operator()( ServiceImplT * p ) const {
210*b1cdbd2cSJim Jagielski         return static_cast<css::lang::XServiceInfo *>(p);
211*b1cdbd2cSJim Jagielski     }
212*b1cdbd2cSJim Jagielski };
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT, typename WithArgsT>
215*b1cdbd2cSJim Jagielski struct CreateFunc;
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT>
218*b1cdbd2cSJim Jagielski struct CreateFunc<ImplT, PostProcessFuncT, with_args<false> > {
219*b1cdbd2cSJim Jagielski     PostProcessFuncT const m_postProcessFunc;
CreateFunccomphelper::service_decl::detail::CreateFunc220*b1cdbd2cSJim Jagielski     explicit CreateFunc( PostProcessFuncT const& postProcessFunc )
221*b1cdbd2cSJim Jagielski         : m_postProcessFunc(postProcessFunc) {}
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski     css::uno::Reference<css::uno::XInterface>
operator ()comphelper::service_decl::detail::CreateFunc224*b1cdbd2cSJim Jagielski     operator()( ServiceDecl const& rServiceDecl,
225*b1cdbd2cSJim Jagielski                 css::uno::Sequence<css::uno::Any> const&,
226*b1cdbd2cSJim Jagielski                 css::uno::Reference<css::uno::XComponentContext>
227*b1cdbd2cSJim Jagielski                 const& xContext ) const
228*b1cdbd2cSJim Jagielski     {
229*b1cdbd2cSJim Jagielski         return m_postProcessFunc(
230*b1cdbd2cSJim Jagielski             new ImplT( rServiceDecl, xContext ) );
231*b1cdbd2cSJim Jagielski     }
232*b1cdbd2cSJim Jagielski };
233*b1cdbd2cSJim Jagielski 
234*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT>
235*b1cdbd2cSJim Jagielski struct CreateFunc<ImplT, PostProcessFuncT, with_args<true> > {
236*b1cdbd2cSJim Jagielski     PostProcessFuncT const m_postProcessFunc;
CreateFunccomphelper::service_decl::detail::CreateFunc237*b1cdbd2cSJim Jagielski     explicit CreateFunc( PostProcessFuncT const& postProcessFunc )
238*b1cdbd2cSJim Jagielski         : m_postProcessFunc(postProcessFunc) {}
239*b1cdbd2cSJim Jagielski 
240*b1cdbd2cSJim Jagielski     css::uno::Reference<css::uno::XInterface>
operator ()comphelper::service_decl::detail::CreateFunc241*b1cdbd2cSJim Jagielski     operator()( ServiceDecl const& rServiceDecl,
242*b1cdbd2cSJim Jagielski                 css::uno::Sequence<css::uno::Any> const& args,
243*b1cdbd2cSJim Jagielski                 css::uno::Reference<css::uno::XComponentContext>
244*b1cdbd2cSJim Jagielski                 const& xContext ) const
245*b1cdbd2cSJim Jagielski     {
246*b1cdbd2cSJim Jagielski         return m_postProcessFunc(
247*b1cdbd2cSJim Jagielski             new ImplT( rServiceDecl, args, xContext ) );
248*b1cdbd2cSJim Jagielski     }
249*b1cdbd2cSJim Jagielski };
250*b1cdbd2cSJim Jagielski 
251*b1cdbd2cSJim Jagielski } // namespace detail
252*b1cdbd2cSJim Jagielski 
253*b1cdbd2cSJim Jagielski /** Defines a service implementation class.
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski     @tpl ImplT_ service implementation class
256*b1cdbd2cSJim Jagielski     @WithArgsT whether the implementation class ctor expects arguments
257*b1cdbd2cSJim Jagielski                (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>)
258*b1cdbd2cSJim Jagielski                or just (uno::Reference<uno::XComponentContext>)
259*b1cdbd2cSJim Jagielski */
260*b1cdbd2cSJim Jagielski template <typename ImplT_, typename WithArgsT = with_args<false> >
261*b1cdbd2cSJim Jagielski struct serviceimpl_base {
262*b1cdbd2cSJim Jagielski     typedef ImplT_ ImplT;
263*b1cdbd2cSJim Jagielski 
264*b1cdbd2cSJim Jagielski     detail::CreateFuncF const m_createFunc;
265*b1cdbd2cSJim Jagielski 
266*b1cdbd2cSJim Jagielski     typedef detail::PostProcessDefault<ImplT> PostProcessDefaultT;
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski     /** Default ctor.  Implementation class without args, expecting
269*b1cdbd2cSJim Jagielski         component context as single argument.
270*b1cdbd2cSJim Jagielski     */
serviceimpl_basecomphelper::service_decl::serviceimpl_base271*b1cdbd2cSJim Jagielski     serviceimpl_base() : m_createFunc(
272*b1cdbd2cSJim Jagielski         detail::CreateFunc<ImplT, PostProcessDefaultT, WithArgsT>(
273*b1cdbd2cSJim Jagielski             PostProcessDefaultT() ) ) {}
274*b1cdbd2cSJim Jagielski 
275*b1cdbd2cSJim Jagielski     /** Ctor to pass a post processing function/functor.
276*b1cdbd2cSJim Jagielski 
277*b1cdbd2cSJim Jagielski         @tpl PostProcessDefaultT let your compiler deduce this
278*b1cdbd2cSJim Jagielski         @param postProcessFunc function/functor that gets the yet unacquired
279*b1cdbd2cSJim Jagielski                                ImplT_ pointer returning a
280*b1cdbd2cSJim Jagielski                                uno::Reference<uno::XInterface>
281*b1cdbd2cSJim Jagielski     */
282*b1cdbd2cSJim Jagielski     template <typename PostProcessFuncT>
serviceimpl_basecomphelper::service_decl::serviceimpl_base283*b1cdbd2cSJim Jagielski     explicit serviceimpl_base( PostProcessFuncT const& postProcessFunc )
284*b1cdbd2cSJim Jagielski         : m_createFunc( detail::CreateFunc<ImplT, PostProcessFuncT, WithArgsT>(
285*b1cdbd2cSJim Jagielski                             postProcessFunc ) ) {}
286*b1cdbd2cSJim Jagielski };
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski template <typename ImplT_, typename WithArgsT = with_args<false> >
289*b1cdbd2cSJim Jagielski struct class_ : public serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT >
290*b1cdbd2cSJim Jagielski {
291*b1cdbd2cSJim Jagielski     typedef serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > baseT;
292*b1cdbd2cSJim Jagielski     /** Default ctor.  Implementation class without args, expecting
293*b1cdbd2cSJim Jagielski         component context as single argument.
294*b1cdbd2cSJim Jagielski     */
class_comphelper::service_decl::class_295*b1cdbd2cSJim Jagielski     class_() : baseT() {}
296*b1cdbd2cSJim Jagielski     template <typename PostProcessFuncT>
297*b1cdbd2cSJim Jagielski     /** Ctor to pass a post processing function/functor.
298*b1cdbd2cSJim Jagielski 
299*b1cdbd2cSJim Jagielski         @tpl PostProcessDefaultT let your compiler deduce this
300*b1cdbd2cSJim Jagielski         @param postProcessFunc function/functor that gets the yet unacquired
301*b1cdbd2cSJim Jagielski                                ImplT_ pointer returning a
302*b1cdbd2cSJim Jagielski                                uno::Reference<uno::XInterface>
303*b1cdbd2cSJim Jagielski     */
class_comphelper::service_decl::class_304*b1cdbd2cSJim Jagielski     explicit class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {}
305*b1cdbd2cSJim Jagielski };
306*b1cdbd2cSJim Jagielski 
307*b1cdbd2cSJim Jagielski //
308*b1cdbd2cSJim Jagielski // component_... helpers with arbitrary service declarations:
309*b1cdbd2cSJim Jagielski //
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_getFactory(z_, n_, unused_) \
312*b1cdbd2cSJim Jagielski     if (pRet == 0) \
313*b1cdbd2cSJim Jagielski         pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName);
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski /** The following preprocessor repetitions generate functions like
316*b1cdbd2cSJim Jagielski 
317*b1cdbd2cSJim Jagielski     <pre>
318*b1cdbd2cSJim Jagielski         inline void * component_getFactoryHelper(
319*b1cdbd2cSJim Jagielski             sal_Char const* pImplName,
320*b1cdbd2cSJim Jagielski             ::com::sun::star::lang::XMultiServiceFactory *,
321*b1cdbd2cSJim Jagielski             ::com::sun::star::registry::XRegistryKey * xRegistryKey,
322*b1cdbd2cSJim Jagielski             ServiceDecl const& s0, ServiceDecl const& s1, ... );
323*b1cdbd2cSJim Jagielski     </pre>
324*b1cdbd2cSJim Jagielski 
325*b1cdbd2cSJim Jagielski     which call on the passed service declarations.
326*b1cdbd2cSJim Jagielski 
327*b1cdbd2cSJim Jagielski     The maximum number of service declarations can be set by defining
328*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS; its default is 8.
329*b1cdbd2cSJim Jagielski */
330*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_make(z_, n_, unused_) \
331*b1cdbd2cSJim Jagielski inline void * component_getFactoryHelper( \
332*b1cdbd2cSJim Jagielski     sal_Char const* pImplName, \
333*b1cdbd2cSJim Jagielski     ::com::sun::star::lang::XMultiServiceFactory *, \
334*b1cdbd2cSJim Jagielski     ::com::sun::star::registry::XRegistryKey *, \
335*b1cdbd2cSJim Jagielski     BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \
336*b1cdbd2cSJim Jagielski { \
337*b1cdbd2cSJim Jagielski     void * pRet = 0; \
338*b1cdbd2cSJim Jagielski     BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \
339*b1cdbd2cSJim Jagielski     return pRet; \
340*b1cdbd2cSJim Jagielski }
341*b1cdbd2cSJim Jagielski 
342*b1cdbd2cSJim Jagielski #if ! defined(COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS)
343*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8
344*b1cdbd2cSJim Jagielski #endif
345*b1cdbd2cSJim Jagielski 
346*b1cdbd2cSJim Jagielski BOOST_PP_REPEAT_FROM_TO(1, COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS,
347*b1cdbd2cSJim Jagielski                         COMPHELPER_SERVICEDECL_make, ~)
348*b1cdbd2cSJim Jagielski 
349*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS
350*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_make
351*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_getFactory
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski } // namespace service_decl
354*b1cdbd2cSJim Jagielski } // namespace comphelper
355*b1cdbd2cSJim Jagielski 
356*b1cdbd2cSJim Jagielski /** The following preprocessor macro generates the C access functions,
357*b1cdbd2cSJim Jagielski     that are used to initialize and register the components of a
358*b1cdbd2cSJim Jagielski     shared library object.
359*b1cdbd2cSJim Jagielski 
360*b1cdbd2cSJim Jagielski     If you have, say, written a lib that contains three distinct
361*b1cdbd2cSJim Jagielski     components, each with its own ServiceDecl object, you might want
362*b1cdbd2cSJim Jagielski     to employ the following code:
363*b1cdbd2cSJim Jagielski 
364*b1cdbd2cSJim Jagielski     <pre>
365*b1cdbd2cSJim Jagielski         // must reside outside _any_ namespace
366*b1cdbd2cSJim Jagielski         COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1,
367*b1cdbd2cSJim Jagielski                                        yourServiceDecl2,
368*b1cdbd2cSJim Jagielski                                        yourServiceDecl3);
369*b1cdbd2cSJim Jagielski     </pre>
370*b1cdbd2cSJim Jagielski 
371*b1cdbd2cSJim Jagielski     For your convenience, the COMPHELPER_SERVICEDECL_EXPORTS<N> macro
372*b1cdbd2cSJim Jagielski     comes pre-defined up to N=8, if you should need more arguments,
373*b1cdbd2cSJim Jagielski     call COMPHELPER_SERVICEDECL_make_exports directly, like this:
374*b1cdbd2cSJim Jagielski 
375*b1cdbd2cSJim Jagielski     <pre>
376*b1cdbd2cSJim Jagielski         // must reside outside _any_ namespace
377*b1cdbd2cSJim Jagielski         COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN));
378*b1cdbd2cSJim Jagielski     </pre>
379*b1cdbd2cSJim Jagielski 
380*b1cdbd2cSJim Jagielski     Note the missing colons between the bracketed arguments.
381*b1cdbd2cSJim Jagielski  */
382*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_make_exports(varargs_ )  \
383*b1cdbd2cSJim Jagielski extern "C" \
384*b1cdbd2cSJim Jagielski { \
385*b1cdbd2cSJim Jagielski     SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char**  ppEnvTypeName, \
386*b1cdbd2cSJim Jagielski                                                           uno_Environment** /*ppEnv*/ ) \
387*b1cdbd2cSJim Jagielski     { \
388*b1cdbd2cSJim Jagielski         *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; \
389*b1cdbd2cSJim Jagielski     } \
390*b1cdbd2cSJim Jagielski  \
391*b1cdbd2cSJim Jagielski     SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( sal_Char const*                                pImplName, \
392*b1cdbd2cSJim Jagielski                                          ::com::sun::star::lang::XMultiServiceFactory*  pServiceManager, \
393*b1cdbd2cSJim Jagielski                                          ::com::sun::star::registry::XRegistryKey*      pRegistryKey ) \
394*b1cdbd2cSJim Jagielski     { \
395*b1cdbd2cSJim Jagielski         return component_getFactoryHelper( pImplName, pServiceManager, \
396*b1cdbd2cSJim Jagielski                                            pRegistryKey, \
397*b1cdbd2cSJim Jagielski                                            BOOST_PP_SEQ_ENUM(varargs_) ); \
398*b1cdbd2cSJim Jagielski     } \
399*b1cdbd2cSJim Jagielski }
400*b1cdbd2cSJim Jagielski 
401*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS1(comp0_) \
402*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_))
403*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS2(comp0_,comp1_) \
404*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_))
405*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS3(comp0_,comp1_,comp2_) \
406*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_))
407*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS4(comp0_,comp1_,comp2_,comp3_) \
408*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_))
409*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS5(comp0_,comp1_,comp2_,comp3_,comp4_) \
410*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_))
411*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS6(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_) \
412*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_))
413*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS7(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_) \
414*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_))
415*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS8(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_,comp7_) \
416*b1cdbd2cSJim Jagielski     COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)(comp7_))
417*b1cdbd2cSJim Jagielski 
418*b1cdbd2cSJim Jagielski #endif //  ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED)
419*b1cdbd2cSJim Jagielski 
420