1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #ifndef INCLUDED_FRAMEWORK_INC_MACROS_XSERVICEINFO_HXX
21 #define INCLUDED_FRAMEWORK_INC_MACROS_XSERVICEINFO_HXX
22 
23 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 
26 #include <com/sun/star/uno/Reference.hxx>
27 #include <com/sun/star/uno/Sequence.hxx>
28 #include <com/sun/star/uno/XComponentContext.hpp>
29 #include <cppuhelper/factory.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <rtl/ustring.hxx>
33 
34 namespace framework{
35 
36 /*
37     macros for declaration and definition of XServiceInfo
38     Please use follow public macros only!
39 
40     2)  DEFINE_XSERVICEINFO_MULTISERVICE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )          => use it to define XServiceInfo for multi service mode
41     3)  DEFINE_XSERVICEINFO_ONEINSTANCESERVICE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )    => use it to define XServiceInfo for one instance service mode
42     4)  DEFINE_INIT_SERVICE( CLASS )                                                                        => use it to implement your own impl_initService() method, which is necessary for initializing object by using his own reference!
43 */
44 
45 #define PRIVATE_DEFINE_XSERVICEINFO_BASE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )                                                  \
46                                                                                                                                                     \
47     OUString SAL_CALL CLASS::getImplementationName()                                                            \
48     {                                                                                                                                               \
49         return impl_getStaticImplementationName();                                                                                                  \
50     }                                                                                                                                               \
51                                                                                                                                                     \
52     sal_Bool SAL_CALL CLASS::supportsService( const OUString& sServiceName )                                    \
53     {                                                                                                                                               \
54         return cppu::supportsService(this, sServiceName);                                                                                           \
55     }                                                                                                                                               \
56                                                                                                                                                     \
57     css::uno::Sequence< OUString > SAL_CALL CLASS::getSupportedServiceNames()                                   \
58     {                                                                                                                                               \
59         return impl_getStaticSupportedServiceNames();                                                                                               \
60     }                                                                                                                                               \
61                                                                                                                                                     \
62     css::uno::Sequence< OUString > CLASS::impl_getStaticSupportedServiceNames()                                                                     \
63     {                                                                                                                                               \
64         css::uno::Sequence< OUString > seqServiceNames { SERVICENAME };                                                                             \
65         return seqServiceNames;                                                                                                                     \
66     }                                                                                                                                               \
67                                                                                                                                                     \
68     OUString CLASS::impl_getStaticImplementationName()                                                                                              \
69     {                                                                                                                                               \
70         return IMPLEMENTATIONNAME;                                                                                                                 \
71     }
72 
73 #define PRIVATE_DEFINE_XSERVICEINFO_OLDSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )                                              \
74     PRIVATE_DEFINE_XSERVICEINFO_BASE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )                                                      \
75     /* Attention: To avoid against wrong ref counts during our own initialize procedure, we must                 */                                 \
76     /*            use right EXTERNAL handling of them. That's why you should do nothing in your ctor, which could*/                                 \
77     /*            work on your ref count! All other things are allowed. Do work with your own reference - please */                                 \
78     /*            use "impl_initService()" method.                                                               */                                 \
79     css::uno::Reference< css::uno::XInterface > SAL_CALL CLASS::impl_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )  \
80     {                                                                                                                                                                                              \
81         /* create new instance of service */                                                                                                                                                       \
82         CLASS* pClass = new CLASS( xServiceManager );                                                                                                                                              \
83         /* hold it alive by increasing his ref count!!! */                                                                                                                                         \
84         css::uno::Reference< css::uno::XInterface > xService( static_cast< XINTERFACECAST* >(pClass), css::uno::UNO_QUERY );                                                                       \
85         /* initialize new service instance ... he can use his own refcount ... we hold it! */                                                                                                      \
86         pClass->impl_initService();                                                                                                                                                                \
87         /* return new created service as reference */                                                                                                                                              \
88         return xService;                                                                                                                                                                           \
89     }
90 
91 #define PRIVATE_DEFINE_XSERVICEINFO_NEWSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )                                              \
92     PRIVATE_DEFINE_XSERVICEINFO_BASE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )                                                      \
93     /* Attention: To avoid against wrong ref counts during our own initialize procedure, we must                 */                                 \
94     /*            use right EXTERNAL handling of them. That's why you should do nothing in your ctor, which could*/                                 \
95     /*            work on your ref count! All other things are allowed. Do work with your own reference - please */                                 \
96     /*            use "impl_initService()" method.                                                               */                                 \
97     css::uno::Reference< css::uno::XInterface > SAL_CALL CLASS::impl_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )\
98     {                                                                                                                                                               \
99         /* retrieve component context from the given service manager */                                                                                             \
100         css::uno::Reference< css::uno::XComponentContext > xComponentContext(                                                                                       \
101             comphelper::getComponentContext( xServiceManager ) );                                                                                                   \
102         /* create new instance of service */                                                                                                                        \
103         CLASS* pClass = new CLASS( xComponentContext );                                                                                                             \
104         /* hold it alive by increasing his ref count!!! */                                                                                                          \
105         css::uno::Reference< css::uno::XInterface > xService( static_cast< XINTERFACECAST* >(pClass), css::uno::UNO_QUERY );                                        \
106         /* initialize new service instance ... he can use his own refcount ... we hold it! */                                                                       \
107         pClass->impl_initService();                                                                                                                                 \
108         /* return new created service as reference */                                                                                                               \
109         return xService;                                                                                                                                            \
110     }
111 
112 #define PRIVATE_DEFINE_SINGLEFACTORY( CLASS )                                                                                                                           \
113     css::uno::Reference< css::lang::XSingleServiceFactory > CLASS::impl_createFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )  \
114     {                                                                                                                                                                   \
115         css::uno::Reference< css::lang::XSingleServiceFactory > xReturn ( cppu::createSingleFactory (   xServiceManager                             ,                   \
116                                                                                                         CLASS::impl_getStaticImplementationName()   ,                   \
117                                                                                                         CLASS::impl_createInstance                  ,                   \
118                                                                                                         CLASS::impl_getStaticSupportedServiceNames()                    \
119                                                                                                     )                                                                   \
120                                                                         );                                                                                              \
121         return xReturn;                                                                                                                                                 \
122     }
123 
124 #define PRIVATE_DEFINE_ONEINSTANCEFACTORY( CLASS )                                                                                                                      \
125     css::uno::Reference< css::lang::XSingleServiceFactory > CLASS::impl_createFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )  \
126     {                                                                                                                                                                   \
127         css::uno::Reference< css::lang::XSingleServiceFactory > xReturn ( cppu::createOneInstanceFactory    (   xServiceManager                             ,           \
128                                                                                                                 CLASS::impl_getStaticImplementationName()   ,           \
129                                                                                                                 CLASS::impl_createInstance                  ,           \
130                                                                                                                 CLASS::impl_getStaticSupportedServiceNames()            \
131                                                                                                             )                                                           \
132                                                                         );                                                                                              \
133         return xReturn;                                                                                                                                                 \
134     }
135 
136 #define DECLARE_XSERVICEINFO_NOFACTORY                                                                                                                                                                                                  \
137     /* interface XServiceInfo */                                                                                                                                                                                                        \
138     virtual OUString                                        SAL_CALL getImplementationName              (                                   ) override;   \
139     virtual sal_Bool                                        SAL_CALL supportsService                    ( const OUString&   sServiceName    ) override;   \
140     virtual css::uno::Sequence< OUString >                  SAL_CALL getSupportedServiceNames           (                                   ) override;   \
141     /* Helper for XServiceInfo */                                                                                                                                                                                 \
142     static css::uno::Sequence< OUString >                   impl_getStaticSupportedServiceNames(                                   );                                                                    \
143     static OUString                                         impl_getStaticImplementationName   (                                   );                                                                    \
144     /* Helper for initialization of service by using own reference! */                                                                                                                                            \
145     void                                                    impl_initService                   (                                   );                                                                    \
146 
147 #define DEFINE_XSERVICEINFO_MULTISERVICE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )              \
148     PRIVATE_DEFINE_XSERVICEINFO_OLDSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )              \
149     PRIVATE_DEFINE_SINGLEFACTORY( CLASS )
150 
151 #define DEFINE_XSERVICEINFO_ONEINSTANCESERVICE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )        \
152     PRIVATE_DEFINE_XSERVICEINFO_OLDSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )              \
153     PRIVATE_DEFINE_ONEINSTANCEFACTORY( CLASS )
154 
155 #define DEFINE_XSERVICEINFO_MULTISERVICE_2( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )            \
156     PRIVATE_DEFINE_XSERVICEINFO_NEWSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )              \
157     PRIVATE_DEFINE_SINGLEFACTORY( CLASS )
158 
159 #define DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )      \
160     PRIVATE_DEFINE_XSERVICEINFO_NEWSTYLE( CLASS, XINTERFACECAST, SERVICENAME, IMPLEMENTATIONNAME )              \
161     PRIVATE_DEFINE_ONEINSTANCEFACTORY( CLASS )
162 
163 //  public
164 //  implementation of service initialize!
165 //  example of using:   DEFINE_INIT_SERVICE( MyClassName,
166 //                          {
167 //                              ...
168 //                              Reference< XInterface > xThis( this, UNO_QUERY );
169 //                              myMember* pMember = new myMember( xThis );
170 //                              ...
171 //                          }
172 //                      )
173 #define DEFINE_INIT_SERVICE( CLASS, FUNCTIONBODY )                                                              \
174     void CLASS::impl_initService()                                                                     \
175     {                                                                                                           \
176         FUNCTIONBODY                                                                                            \
177     }
178 
179 }       //  namespace framework
180 
181 #endif // INCLUDED_FRAMEWORK_INC_MACROS_XSERVICEINFO_HXX
182 
183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
184