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