1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_extensions.hxx" 30 #include "res_services.hxx" 31 32 #include <vos/mutex.hxx> 33 #include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type 34 #include <cppuhelper/factory.hxx> // helper for factories 35 #include <cppuhelper/implbase3.hxx> // helper for implementations 36 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <com/sun/star/script/XInvocation.hpp> 39 #include <com/sun/star/script/XTypeConverter.hpp> 40 #include <com/sun/star/reflection/InvocationTargetException.hpp> 41 #include <com/sun/star/beans/XExactName.hpp> 42 #include <com/sun/star/beans/PropertyValue.hpp> 43 #include <com/sun/star/beans/PropertyState.hpp> 44 45 #include <tools/resmgr.hxx> 46 #include <tools/rcid.h> 47 #include <tools/resary.hxx> 48 #include <vcl/svapp.hxx> 49 50 #include <rtl/ustring.hxx> 51 #include <rtl/strbuf.hxx> 52 53 using namespace vos; 54 using namespace rtl; 55 using namespace com::sun::star::uno; 56 using namespace com::sun::star::lang; 57 using namespace com::sun::star::registry; 58 using namespace com::sun::star::script; 59 using namespace com::sun::star::beans; 60 using namespace com::sun::star::reflection; 61 62 //------------------------------------------------------------------------ 63 //------------------------------------------------------------------------ 64 //------------------------------------------------------------------------ 65 class ResourceService : public cppu::WeakImplHelper3< XInvocation, XExactName, XServiceInfo > 66 { 67 public: 68 ResourceService( const Reference< XMultiServiceFactory > & ); 69 ~ResourceService(); 70 71 // XServiceInfo 72 OUString SAL_CALL getImplementationName() throw(); 73 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(); 74 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(); 75 76 static Sequence< OUString > getSupportedServiceNames_Static(void) throw(); 77 static OUString getImplementationName_Static() throw() 78 { 79 return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.extensions.ResourceService")); 80 } 81 static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); 82 83 // XExactName 84 OUString SAL_CALL getExactName( const OUString & ApproximateName ) throw(RuntimeException); 85 86 // XInvokation 87 Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(RuntimeException); 88 Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam) throw(IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException); 89 void SAL_CALL setValue(const OUString& PropertyName, const Any& Value) throw(UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException); 90 Any SAL_CALL getValue(const OUString& PropertyName) throw(UnknownPropertyException, RuntimeException); 91 sal_Bool SAL_CALL hasMethod(const OUString& Name) throw(RuntimeException); 92 sal_Bool SAL_CALL hasProperty(const OUString& Name) throw(RuntimeException); 93 private: 94 Reference< XTypeConverter > getTypeConverter() const; 95 Reference< XInvocation > getDefaultInvocation() const; 96 97 Reference< XMultiServiceFactory > xSMgr; 98 Reference< XInvocation > xDefaultInvocation; 99 Reference< XTypeConverter > xTypeConverter; 100 OUString aFileName; 101 ResMgr * pResMgr; 102 }; 103 104 105 //----------------------------------------------------------------------------- 106 ResourceService::ResourceService( const Reference< XMultiServiceFactory > & rSMgr ) 107 : xSMgr( rSMgr ) 108 , pResMgr( NULL ) 109 { 110 } 111 112 //----------------------------------------------------------------------------- 113 Reference< XInterface > ResourceService::Create( const Reference< XComponentContext >& _rxContext ) 114 { 115 Reference< XMultiServiceFactory > xFactory( _rxContext->getServiceManager(), UNO_QUERY_THROW ); 116 return *( new ResourceService( xFactory ) ); 117 } 118 119 //----------------------------------------------------------------------------- 120 ResourceService::~ResourceService() 121 { 122 delete pResMgr; 123 } 124 125 // XServiceInfo 126 OUString ResourceService::getImplementationName() throw() 127 { 128 return getImplementationName_Static(); 129 } 130 131 // XServiceInfo 132 sal_Bool SAL_CALL ResourceService::supportsService(const OUString& ServiceName) throw() 133 { 134 Sequence< OUString > aSNL = getSupportedServiceNames(); 135 const OUString * pArray = aSNL.getConstArray(); 136 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 137 if( pArray[i] == ServiceName ) 138 return sal_True; 139 return sal_False; 140 } 141 142 // XServiceInfo 143 Sequence< OUString > SAL_CALL ResourceService::getSupportedServiceNames(void) throw() 144 { 145 return getSupportedServiceNames_Static(); 146 } 147 148 // ResourceService 149 Sequence< OUString > ResourceService::getSupportedServiceNames_Static(void) throw() 150 { 151 Sequence< OUString > aSNS( 1 ); 152 aSNS.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.VclStringResourceLoader")); 153 return aSNS; 154 } 155 156 // ResourceService 157 Reference< XTypeConverter > ResourceService::getTypeConverter() const 158 { 159 OGuard aGuard( Application::GetSolarMutex() ); 160 if( xSMgr.is() ) 161 { 162 Reference< XTypeConverter > xConv( xSMgr->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter" ))), UNO_QUERY ); 163 ((ResourceService*)this)->xTypeConverter = xConv; 164 } 165 return xTypeConverter; 166 } 167 168 // ResourceService 169 Reference< XInvocation > ResourceService::getDefaultInvocation() const 170 { 171 OGuard aGuard( Application::GetSolarMutex() ); 172 /* f�hrt zur Zeit noch zu einer rekursion 173 if( xSMgr.is() ) 174 { 175 Reference< XSingleServiceFactory > xFact( xSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.Invocation") ), UNO_QUERY ); 176 if( xFact.is() ) 177 { 178 Sequence< Any > aArgs( 1 ); 179 Reference< XInterface > xThis( *this ); 180 aArgs.getArray()[0].set( &xThis, XInterface_Reference< get >lection() ); 181 Reference< XInvokation > xI( xFact->createInstanceWithArguments( aArgs ), UNO_QUERY ); 182 ((ResourceService*)this)->xDefaultInvocation = xI; 183 } 184 } 185 */ 186 return xDefaultInvocation; 187 } 188 189 // XExactName 190 OUString SAL_CALL ResourceService::getExactName( const OUString & ApproximateName ) throw(RuntimeException) 191 { 192 OUString aName( ApproximateName ); 193 aName = aName.toAsciiLowerCase(); 194 if( aName.equalsAscii("filename") ) 195 return OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")); 196 else if( aName.equalsAscii("getstring" )) 197 return OUString(RTL_CONSTASCII_USTRINGPARAM("getString")); 198 else if( aName.equalsAscii("getstrings" )) 199 return OUString(RTL_CONSTASCII_USTRINGPARAM("getStrings")); 200 else if( aName.equalsAscii("hasstring") ) 201 return OUString(RTL_CONSTASCII_USTRINGPARAM("hasString")); 202 else if( aName.equalsAscii("hasstrings") ) 203 return OUString(RTL_CONSTASCII_USTRINGPARAM("hasStrings")); 204 else if( aName.equalsAscii("getstringlist") ) 205 return OUString(RTL_CONSTASCII_USTRINGPARAM("getStringList")); 206 else if( aName.equalsAscii("hasStringList") ) 207 return OUString(RTL_CONSTASCII_USTRINGPARAM("hasStringList")); 208 Reference< XExactName > xEN( getDefaultInvocation(), UNO_QUERY ); 209 if( xEN.is() ) 210 return xEN->getExactName( ApproximateName ); 211 return OUString(); 212 } 213 214 // XInvokation 215 Reference< XIntrospectionAccess > SAL_CALL ResourceService::getIntrospection(void) 216 throw(RuntimeException) 217 { 218 Reference< XInvocation > xI = getDefaultInvocation(); 219 if( xI.is() ) 220 return xI->getIntrospection(); 221 return Reference< XIntrospectionAccess >(); 222 } 223 224 // XInvokation 225 Any SAL_CALL ResourceService::invoke 226 ( 227 const OUString& FunctionName, 228 const Sequence< Any >& Params, 229 Sequence< sal_Int16 >& OutParamIndex, 230 Sequence< Any >& OutParam 231 ) 232 throw(IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException) 233 { 234 Any aRet; 235 if( FunctionName.equalsAscii("getString") 236 || FunctionName.equalsAscii("getStrings" ) 237 || FunctionName.equalsAscii("hasString" ) 238 || FunctionName.equalsAscii("hasStrings" ) 239 ) 240 { 241 sal_Int32 nElements = Params.getLength(); 242 if( nElements < 1 ) 243 throw IllegalArgumentException(); 244 if( nElements > 1 && (FunctionName.equalsAscii("getString") || FunctionName.equalsAscii("hasString") ) ) 245 throw IllegalArgumentException(); 246 if( !pResMgr ) 247 throw IllegalArgumentException(); 248 249 Sequence< OUString > aStrings( Params.getLength() ); 250 Sequence< sal_Bool > aBools( Params.getLength() ); 251 const Any* pIn = Params.getConstArray(); 252 OUString* pOutString = aStrings.getArray(); 253 sal_Bool* pOutBool = aBools.getArray(); 254 255 Reference< XTypeConverter > xC = getTypeConverter(); 256 bool bGetBranch = FunctionName.equalsAscii( "getString" ) || FunctionName.equalsAscii( "getStrings" ); 257 258 OGuard aGuard( Application::GetSolarMutex() ); 259 for( sal_Int32 n = 0; n < nElements; n++ ) 260 { 261 sal_Int32 nId = 0; 262 if( !(pIn[n] >>= nId) ) 263 { 264 if( xC.is() ) 265 { 266 xC->convertToSimpleType( pIn[n], TypeClass_LONG ) >>= nId; 267 } 268 else 269 throw CannotConvertException(); 270 } 271 if( nId > 0xFFFF || nId < 0 ) 272 throw IllegalArgumentException(); 273 274 if( bGetBranch ) 275 { 276 ResId aId( (sal_uInt16)nId, *pResMgr ); 277 aId.SetRT( RSC_STRING ); 278 if( pResMgr->IsAvailable( aId ) ) 279 { 280 String aStr( aId ); 281 pOutString[n] = aStr; 282 } 283 else 284 throw IllegalArgumentException(); 285 } 286 else // hasString(s) 287 { 288 sal_Bool bRet = sal_False; 289 if( pResMgr ) 290 { 291 ResId aId( (sal_uInt16)nId, *pResMgr ); 292 aId.SetRT( RSC_STRING ); 293 bRet = pResMgr->IsAvailable( aId ); 294 } 295 pOutBool[n] = bRet; 296 } 297 } 298 if( FunctionName.equalsAscii("getString") ) 299 aRet <<= pOutString[0]; 300 else if( FunctionName.equalsAscii("getStrings" ) ) 301 aRet <<= aStrings; 302 else if( FunctionName.equalsAscii("hasString" ) ) 303 aRet <<= pOutBool[0]; 304 else 305 aRet <<= aBools; 306 } 307 else if( FunctionName.equalsAscii("getStringList") || FunctionName.equalsAscii("hasStringList" ) ) 308 { 309 if( Params.getLength() != 1 ) 310 throw IllegalArgumentException(); 311 Reference< XTypeConverter > xC = getTypeConverter(); 312 OGuard aGuard( Application::GetSolarMutex() ); 313 314 sal_Int32 nId = 0; 315 if( !(Params.getConstArray()[0] >>= nId) ) 316 { 317 if( xC.is() ) 318 { 319 xC->convertToSimpleType( Params.getConstArray()[0], TypeClass_LONG ) >>= nId; 320 } 321 else 322 throw CannotConvertException(); 323 } 324 325 if( FunctionName.equalsAscii("getStringList") ) 326 { 327 ResId aId( (sal_uInt16)nId, *pResMgr ); 328 aId.SetRT( RSC_STRINGARRAY ); 329 if( pResMgr->IsAvailable( aId ) ) 330 { 331 ResStringArray aStr( aId ); 332 int nEntries = aStr.Count(); 333 Sequence< PropertyValue > aPropSeq( nEntries ); 334 PropertyValue* pOut = aPropSeq.getArray(); 335 for( int i = 0; i < nEntries; i++ ) 336 { 337 pOut[i].Name = aStr.GetString( i ); 338 pOut[i].Handle = -1; 339 pOut[i].Value <<= aStr.GetValue( i ); 340 pOut[i].State = PropertyState_DIRECT_VALUE; 341 } 342 aRet <<= aPropSeq; 343 } 344 else 345 throw IllegalArgumentException(); 346 } 347 else // hasStringList 348 { 349 sal_Bool bRet = sal_False; 350 if( pResMgr ) 351 { 352 ResId aId( (sal_uInt16)nId, *pResMgr ); 353 aId.SetRT( RSC_STRINGARRAY ); 354 bRet = pResMgr->IsAvailable( aId ); 355 } 356 aRet <<= bRet; 357 } 358 } 359 else 360 { 361 Reference< XInvocation > xI = getDefaultInvocation(); 362 if( xI.is() ) 363 return xI->invoke( FunctionName, Params, OutParamIndex, OutParam ); 364 else 365 throw IllegalArgumentException(); 366 } 367 return aRet; 368 } 369 370 // XInvokation 371 void SAL_CALL ResourceService::setValue(const OUString& PropertyName, const Any& Value) 372 throw(UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException) 373 { 374 if( PropertyName.equalsAscii("FileName") ) 375 { 376 OUString aName; 377 if( !(Value >>= aName) ) 378 { 379 Reference< XTypeConverter > xC = getTypeConverter(); 380 if( xC.is() ) 381 xC->convertToSimpleType( Value, TypeClass_STRING ) >>= aName; 382 else 383 throw CannotConvertException(); 384 } 385 386 OGuard aGuard( Application::GetSolarMutex() ); 387 OStringBuffer aBuf( aName.getLength()+8 ); 388 aBuf.append( OUStringToOString( aName, osl_getThreadTextEncoding() ) ); 389 ResMgr * pRM = ResMgr::CreateResMgr( aBuf.getStr() ); 390 if( !pRM ) 391 throw InvocationTargetException(); 392 if( pResMgr ) 393 delete pResMgr; 394 pResMgr = pRM; 395 aFileName = OStringToOUString( aBuf.makeStringAndClear(), osl_getThreadTextEncoding() ); 396 } 397 else 398 { 399 Reference< XInvocation > xI = getDefaultInvocation(); 400 if( xI.is() ) 401 xI->setValue( PropertyName, Value ); 402 else 403 throw UnknownPropertyException(); 404 } 405 } 406 407 // XInvokation 408 Any SAL_CALL ResourceService::getValue(const OUString& PropertyName) 409 throw(UnknownPropertyException, RuntimeException) 410 { 411 OGuard aGuard( Application::GetSolarMutex() ); 412 if( PropertyName.equalsAscii("FileName" )) 413 return makeAny( aFileName ); 414 415 Reference< XInvocation > xI = getDefaultInvocation(); 416 if( xI.is() ) 417 return xI->getValue( PropertyName ); 418 419 throw UnknownPropertyException(); 420 } 421 422 // XInvokation 423 sal_Bool SAL_CALL ResourceService::hasMethod(const OUString& Name) 424 throw(RuntimeException) 425 { 426 if( Name.equalsAscii("getString") || 427 Name.equalsAscii("getStrings") || 428 Name.equalsAscii("hasString") || 429 Name.equalsAscii("hasStrings") || 430 Name.equalsAscii("getStringList") || 431 Name.equalsAscii("hasStringList") 432 ) 433 return sal_True; 434 else 435 { 436 Reference< XInvocation > xI = getDefaultInvocation(); 437 if( xI.is() ) 438 return xI->hasMethod( Name ); 439 else 440 return sal_False; 441 } 442 } 443 444 // XInvokation 445 sal_Bool SAL_CALL ResourceService::hasProperty(const OUString& Name) 446 throw(RuntimeException) 447 { 448 if( Name.equalsAscii("FileName") ) 449 return sal_True; 450 else 451 { 452 Reference< XInvocation > xI = getDefaultInvocation(); 453 if( xI.is() ) 454 return xI->hasProperty( Name ); 455 else 456 return sal_False; 457 } 458 } 459 460 namespace res 461 { 462 ComponentInfo getComponentInfo_VclStringResourceLoader() 463 { 464 ComponentInfo aInfo; 465 aInfo.aSupportedServices = ResourceService::getSupportedServiceNames_Static(); 466 aInfo.sImplementationName = ResourceService::getImplementationName_Static(); 467 aInfo.pFactory = &ResourceService::Create; 468 return aInfo; 469 } 470 } 471 472