xref: /trunk/main/odk/examples/DevelopersGuide/Components/CppComponent/service1_impl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <osl/interlck.h>
25 #include <osl/mutex.hxx>
26 #include <rtl/uuid.h>
27 #include <cppuhelper/factory.hxx>
28 
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/XTypeProvider.hpp>
31 #include <my_module/XSomething.hpp>
32 
33 
34 using namespace ::rtl; // for OUString
35 using namespace ::com::sun::star; // for odk interfaces
36 using namespace ::com::sun::star::uno; // for basic types
37 
38 namespace my_sc_impl
39 {
40 
getSupportedServiceNames_MyService1Impl()41 Sequence< OUString > SAL_CALL getSupportedServiceNames_MyService1Impl()
42 {
43     Sequence< OUString > names(1);
44     names[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1"));
45     return names;
46 }
47 
getImplementationName_MyService1Impl()48 OUString SAL_CALL getImplementationName_MyService1Impl()
49 {
50     return OUString( RTL_CONSTASCII_USTRINGPARAM(
51                          "my_module.my_sc_implementation.MyService1") );
52 }
53 
54 
55 class MyService1Impl
56     : public ::my_module::XSomething
57     , public lang::XServiceInfo
58     , public lang::XTypeProvider
59 {
60     oslInterlockedCount m_refcount;
61     OUString m_sData;
62     // it's good practice to store the context for further use when you use
63     // other UNO API's in your implementation
64     Reference< XComponentContext > m_xContext;
65 public:
MyService1Impl(Reference<XComponentContext> const & xContext)66     inline MyService1Impl(Reference< XComponentContext > const & xContext) throw ()
67         : m_refcount( 0 ),
68           m_xContext(xContext)
69         {}
70 
~MyService1Impl()71     virtual ~MyService1Impl() {}
72 
73     // XInterface
74     virtual Any SAL_CALL queryInterface( Type const & type );
75     virtual void SAL_CALL acquire()
76         throw ();
77     virtual void SAL_CALL release()
78         throw ();
79     // XTypeProvider
80     virtual Sequence< Type > SAL_CALL getTypes();
81     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId();
82     // XSomething
83     virtual OUString SAL_CALL methodOne( OUString const & str );
84     virtual OUString SAL_CALL methodTwo( );
85     // XServiceInfo
86     virtual OUString SAL_CALL getImplementationName();
87     virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName );
88     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames();
89 };
90 
91 // XInterface implementation
queryInterface(Type const & type)92 Any MyService1Impl::queryInterface( Type const & type )
93 {
94     if (type.equals(::cppu::UnoType< Reference< XInterface > >::get()))
95     {
96         // return XInterface interface
97         // (resolve ambiguity by casting to lang::XTypeProvider)
98         Reference< XInterface > x(
99             static_cast< lang::XTypeProvider * >( this ) );
100         return makeAny( x );
101     }
102     if (type.equals(::cppu::UnoType< Reference< lang::XTypeProvider > >::get()))
103     {
104         // return XInterface interface
105         Reference< XInterface > x(
106             static_cast< lang::XTypeProvider * >( this ) );
107         return makeAny( x );
108     }
109     if (type.equals(::cppu::UnoType< Reference< lang::XServiceInfo > >::get()))
110     {
111         // return XServiceInfo interface
112         Reference< lang::XServiceInfo > x(
113             static_cast< lang::XServiceInfo * >( this ) );
114         return makeAny( x );
115     }
116     if (type.equals(::cppu::UnoType< Reference< ::my_module::XSomething > >::get()))
117     {
118         // return sample interface
119         Reference< ::my_module::XSomething > x(
120             static_cast< ::my_module::XSomething * >( this ) );
121         return makeAny( x );
122     }
123     // querying for unsupported type
124     return Any();
125 }
126 
acquire()127 void MyService1Impl::acquire()
128     throw ()
129 {
130     // thread-safe incrementation of reference count
131     ::osl_incrementInterlockedCount( &m_refcount );
132 }
133 
release()134 void MyService1Impl::release()
135     throw ()
136 {
137     // thread-safe decrementation of reference count
138     if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
139     {
140         delete this; // shutdown this object
141     }
142 }
143 
144 // XTypeProvider implementation
getTypes()145 Sequence< Type > MyService1Impl::getTypes()
146 {
147     Sequence< Type > seq( 3 );
148     seq[ 0 ] = ::cppu::UnoType< Reference< lang::XTypeProvider > >::get();
149     seq[ 1 ] = ::cppu::UnoType< Reference< lang::XServiceInfo > >::get();
150     seq[ 2 ] = ::cppu::UnoType< Reference< ::my_module::XSomething > >::get();
151     return seq;
152 }
getImplementationId()153 Sequence< sal_Int8 > MyService1Impl::getImplementationId()
154 {
155     static Sequence< sal_Int8 > * s_pId = 0;
156     if (! s_pId)
157     {
158         // create unique id
159         Sequence< sal_Int8 > id( 16 );
160         ::rtl_createUuid( (sal_uInt8 *)id.getArray(), 0, sal_True );
161         // guard initialization with some mutex
162         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
163         if (! s_pId)
164         {
165             static Sequence< sal_Int8 > s_id( id );
166             s_pId = &s_id;
167         }
168     }
169     return *s_pId;
170 }
171 
172 // XSomething implementation
methodOne(OUString const & str)173 OUString MyService1Impl::methodOne( OUString const & str )
174 {
175     m_sData = str;
176     return OUString( RTL_CONSTASCII_USTRINGPARAM(
177         "called methodOne() of MyService1 implementation: ") ) + m_sData;
178 }
179 
methodTwo()180 OUString MyService1Impl::methodTwo( )
181 {
182     return OUString( RTL_CONSTASCII_USTRINGPARAM(
183         "called methodTwo() of MyService1 implementation: ") ) + m_sData;
184 }
185 
186 // XServiceInfo implementation
getImplementationName()187 OUString MyService1Impl::getImplementationName()
188 {
189     // unique implementation name
190     return OUString( RTL_CONSTASCII_USTRINGPARAM(
191                          "my_module.my_sc_implementation.MyService1") );
192 }
supportsService(OUString const & serviceName)193 sal_Bool MyService1Impl::supportsService( OUString const & serviceName )
194 {
195     // this object only supports one service, so the test is simple
196     return serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
197                                          "my_module.MyService1") );
198 }
getSupportedServiceNames()199 Sequence< OUString > MyService1Impl::getSupportedServiceNames()
200 {
201     // this object only supports one service
202     OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1") );
203     return Sequence< OUString >( &serviceName, 1 );
204 }
205 
create_MyService1Impl(Reference<XComponentContext> const & xContext)206 Reference< XInterface > SAL_CALL create_MyService1Impl(
207     Reference< XComponentContext > const & xContext )
208     SAL_THROW( () )
209 {
210     return static_cast< lang::XTypeProvider * >( new MyService1Impl( xContext) );
211 }
212 
213 // forward decl: implemented in service2_impl.cxx
214 Reference< XInterface > SAL_CALL create_MyService2Impl(
215     Reference< XComponentContext > const & ) SAL_THROW( () );
216 
217 }
218 
219 /*
220 extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
221     sal_Char const ** ppEnvTypeName, uno_Environment ** )
222 {
223     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
224 }
225 
226 // This method not longer necessary since OOo 3.4 where the component registration was
227 // was changed to passive component registration. For more details see
228 // https://wiki.openoffice.org/wiki/Passive_Component_Registration
229 //
230 // extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
231 //     lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry )
232 // {
233 //     if (xRegistry)
234 //     {
235 //         try
236 //         {
237 //             // implementation of MyService1A
238 //             Reference< registry::XRegistryKey > xKey(
239 //                 xRegistry->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
240 //                     "my_module.my_sc_implementation.MyService1/UNO/SERVICES") ) ) );
241 //             // subkeys denote implemented services of implementation
242 //             xKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
243 //                 "my_module.MyService1") ) );
244 //             // implementation of MyService1B
245 //             xKey = xRegistry->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
246 //                 "my_module.my_sc_implementation.MyService2/UNO/SERVICES") ) );
247 //             // subkeys denote implemented services of implementation
248 //             xKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
249 //                 "my_module.MyService2") ) );
250 //             return sal_True; // success
251 //         }
252 //         catch (registry::InvalidRegistryException &)
253 //         {
254 //             // function fails if exception caught
255 //         }
256 //     }
257 //     return sal_False;
258 // }
259 
260 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
261     sal_Char const * implName, lang::XMultiServiceFactory * xMgr, void * )
262 {
263     Reference< lang::XSingleComponentFactory > xFactory;
264     if (0 == ::rtl_str_compare( implName, "my_module.my_sc_implementation.MyService1" ))
265     {
266         // create component factory for MyService1 implementation
267         OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1") );
268         xFactory = ::cppu::createSingleComponentFactory(
269             ::my_sc_impl::create_MyService1Impl,
270             OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService1") ),
271             Sequence< OUString >( &serviceName, 1 ) );
272     }
273     else if (0 == ::rtl_str_compare( implName, "my_module.my_sc_implementation.MyService2" ))
274     {
275         // create component factory for MyService12 implementation
276         OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService2") );
277         xFactory = ::cppu::createSingleComponentFactory(
278             ::my_sc_impl::create_MyService2Impl,
279             OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService2") ),
280             Sequence< OUString >( &serviceName, 1 ) );
281     }
282     if (xFactory.is())
283         xFactory->acquire();
284     return xFactory.get(); // return acquired interface pointer or null
285 }
286 */
287