xref: /AOO41X/main/odk/examples/DevelopersGuide/Components/CppComponent/service1_impl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 #include <osl/interlck.h>
36 #include <osl/mutex.hxx>
37 #include <rtl/uuid.h>
38 #include <cppuhelper/factory.hxx>
39 
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/lang/XTypeProvider.hpp>
42 #include <my_module/XSomething.hpp>
43 
44 
45 using namespace ::rtl; // for OUString
46 using namespace ::com::sun::star; // for odk interfaces
47 using namespace ::com::sun::star::uno; // for basic types
48 
49 namespace my_sc_impl
50 {
51 
52 Sequence< OUString > SAL_CALL getSupportedServiceNames_MyService1Impl()
53 {
54     Sequence< OUString > names(1);
55     names[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1"));
56     return names;
57 }
58 
59 OUString SAL_CALL getImplementationName_MyService1Impl()
60 {
61     return OUString( RTL_CONSTASCII_USTRINGPARAM(
62                          "my_module.my_sc_implementation.MyService1") );
63 }
64 
65 
66 class MyService1Impl
67     : public ::my_module::XSomething
68     , public lang::XServiceInfo
69     , public lang::XTypeProvider
70 {
71     oslInterlockedCount m_refcount;
72     OUString m_sData;
73     // it's good practise to store the context for further use when you use
74     // other UNO API's in your implementation
75     Reference< XComponentContext > m_xContext;
76 public:
77     inline MyService1Impl(Reference< XComponentContext > const & xContext) throw ()
78         : m_refcount( 0 ),
79           m_xContext(xContext)
80         {}
81 
82     virtual ~MyService1Impl() {}
83 
84     // XInterface
85     virtual Any SAL_CALL queryInterface( Type const & type )
86         throw (RuntimeException);
87     virtual void SAL_CALL acquire()
88         throw ();
89     virtual void SAL_CALL release()
90         throw ();
91     // XTypeProvider
92     virtual Sequence< Type > SAL_CALL getTypes()
93         throw (RuntimeException);
94     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId()
95         throw (RuntimeException);
96     // XSomething
97     virtual OUString SAL_CALL methodOne( OUString const & str )
98         throw (RuntimeException);
99     virtual OUString SAL_CALL methodTwo( )
100         throw (RuntimeException);
101     // XServiceInfo
102     virtual OUString SAL_CALL getImplementationName()
103         throw (RuntimeException);
104     virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
105         throw (RuntimeException);
106     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
107         throw (RuntimeException);
108 };
109 
110 // XInterface implementation
111 Any MyService1Impl::queryInterface( Type const & type )
112     throw (RuntimeException)
113 {
114     if (type.equals(::cppu::UnoType< Reference< XInterface > >::get()))
115     {
116         // return XInterface interface
117         // (resolve ambiguity by casting to lang::XTypeProvider)
118         Reference< XInterface > x(
119             static_cast< lang::XTypeProvider * >( this ) );
120         return makeAny( x );
121     }
122     if (type.equals(::cppu::UnoType< Reference< lang::XTypeProvider > >::get()))
123     {
124         // return XInterface interface
125         Reference< XInterface > x(
126             static_cast< lang::XTypeProvider * >( this ) );
127         return makeAny( x );
128     }
129     if (type.equals(::cppu::UnoType< Reference< lang::XServiceInfo > >::get()))
130     {
131         // return XServiceInfo interface
132         Reference< lang::XServiceInfo > x(
133             static_cast< lang::XServiceInfo * >( this ) );
134         return makeAny( x );
135     }
136     if (type.equals(::cppu::UnoType< Reference< ::my_module::XSomething > >::get()))
137     {
138         // return sample interface
139         Reference< ::my_module::XSomething > x(
140             static_cast< ::my_module::XSomething * >( this ) );
141         return makeAny( x );
142     }
143     // querying for unsupported type
144     return Any();
145 }
146 
147 void MyService1Impl::acquire()
148     throw ()
149 {
150     // thread-safe incrementation of reference count
151     ::osl_incrementInterlockedCount( &m_refcount );
152 }
153 
154 void MyService1Impl::release()
155     throw ()
156 {
157     // thread-safe decrementation of reference count
158     if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
159     {
160         delete this; // shutdown this object
161     }
162 }
163 
164 // XTypeProvider implementation
165 Sequence< Type > MyService1Impl::getTypes()
166     throw (RuntimeException)
167 {
168     Sequence< Type > seq( 3 );
169     seq[ 0 ] = ::cppu::UnoType< Reference< lang::XTypeProvider > >::get();
170     seq[ 1 ] = ::cppu::UnoType< Reference< lang::XServiceInfo > >::get();
171     seq[ 2 ] = ::cppu::UnoType< Reference< ::my_module::XSomething > >::get();
172     return seq;
173 }
174 Sequence< sal_Int8 > MyService1Impl::getImplementationId()
175     throw (RuntimeException)
176 {
177     static Sequence< sal_Int8 > * s_pId = 0;
178     if (! s_pId)
179     {
180         // create unique id
181         Sequence< sal_Int8 > id( 16 );
182         ::rtl_createUuid( (sal_uInt8 *)id.getArray(), 0, sal_True );
183         // guard initialization with some mutex
184         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
185         if (! s_pId)
186         {
187             static Sequence< sal_Int8 > s_id( id );
188             s_pId = &s_id;
189         }
190     }
191     return *s_pId;
192 }
193 
194 // XSomething implementation
195 OUString MyService1Impl::methodOne( OUString const & str )
196     throw (RuntimeException)
197 {
198     m_sData = str;
199     return OUString( RTL_CONSTASCII_USTRINGPARAM(
200         "called methodOne() of MyService1 implementation: ") ) + m_sData;
201 }
202 
203 OUString MyService1Impl::methodTwo( )
204     throw (RuntimeException)
205 {
206     return OUString( RTL_CONSTASCII_USTRINGPARAM(
207         "called methodTwo() of MyService1 implementation: ") ) + m_sData;
208 }
209 
210 // XServiceInfo implementation
211 OUString MyService1Impl::getImplementationName()
212     throw (RuntimeException)
213 {
214     // unique implementation name
215     return OUString( RTL_CONSTASCII_USTRINGPARAM(
216                          "my_module.my_sc_implementation.MyService1") );
217 }
218 sal_Bool MyService1Impl::supportsService( OUString const & serviceName )
219     throw (RuntimeException)
220 {
221     // this object only supports one service, so the test is simple
222     return serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
223                                          "my_module.MyService1") );
224 }
225 Sequence< OUString > MyService1Impl::getSupportedServiceNames()
226     throw (RuntimeException)
227 {
228     // this object only supports one service
229     OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1") );
230     return Sequence< OUString >( &serviceName, 1 );
231 }
232 
233 Reference< XInterface > SAL_CALL create_MyService1Impl(
234     Reference< XComponentContext > const & xContext )
235     SAL_THROW( () )
236 {
237     return static_cast< lang::XTypeProvider * >( new MyService1Impl( xContext) );
238 }
239 
240 // forward decl: implemented in service2_impl.cxx
241 Reference< XInterface > SAL_CALL create_MyService2Impl(
242     Reference< XComponentContext > const & ) SAL_THROW( () );
243 
244 }
245 
246 /*
247 extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
248     sal_Char const ** ppEnvTypeName, uno_Environment ** )
249 {
250     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
251 }
252 
253 // This method not longer necessary since OOo 3.4 where the component registration was
254 // was changed to passive component registration. For more details see
255 // http://wiki.services.openoffice.org/wiki/Passive_Component_Registration
256 //
257 // extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
258 //     lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry )
259 // {
260 //     if (xRegistry)
261 //     {
262 //         try
263 //         {
264 //             // implementation of MyService1A
265 //             Reference< registry::XRegistryKey > xKey(
266 //                 xRegistry->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
267 //                     "my_module.my_sc_implementation.MyService1/UNO/SERVICES") ) ) );
268 //             // subkeys denote implemented services of implementation
269 //             xKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
270 //                 "my_module.MyService1") ) );
271 //             // implementation of MyService1B
272 //             xKey = xRegistry->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
273 //                 "my_module.my_sc_implementation.MyService2/UNO/SERVICES") ) );
274 //             // subkeys denote implemented services of implementation
275 //             xKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(
276 //                 "my_module.MyService2") ) );
277 //             return sal_True; // success
278 //         }
279 //         catch (registry::InvalidRegistryException &)
280 //         {
281 //             // function fails if exception caught
282 //         }
283 //     }
284 //     return sal_False;
285 // }
286 
287 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
288     sal_Char const * implName, lang::XMultiServiceFactory * xMgr, void * )
289 {
290     Reference< lang::XSingleComponentFactory > xFactory;
291     if (0 == ::rtl_str_compare( implName, "my_module.my_sc_implementation.MyService1" ))
292     {
293         // create component factory for MyService1 implementation
294         OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService1") );
295         xFactory = ::cppu::createSingleComponentFactory(
296             ::my_sc_impl::create_MyService1Impl,
297             OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService1") ),
298             Sequence< OUString >( &serviceName, 1 ) );
299     }
300     else if (0 == ::rtl_str_compare( implName, "my_module.my_sc_implementation.MyService2" ))
301     {
302         // create component factory for MyService12 implementation
303         OUString serviceName( RTL_CONSTASCII_USTRINGPARAM("my_module.MyService2") );
304         xFactory = ::cppu::createSingleComponentFactory(
305             ::my_sc_impl::create_MyService2Impl,
306             OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService2") ),
307             Sequence< OUString >( &serviceName, 1 ) );
308     }
309     if (xFactory.is())
310         xFactory->acquire();
311     return xFactory.get(); // return acquired interface pointer or null
312 }
313 */
314 
315