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