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 ); 81 82 // XInvokation 83 Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void); 84 Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam); 85 void SAL_CALL setValue(const OUString& PropertyName, const Any& Value); 86 Any SAL_CALL getValue(const OUString& PropertyName); 87 sal_Bool SAL_CALL hasMethod(const OUString& Name); 88 sal_Bool SAL_CALL hasProperty(const OUString& Name); 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 ) 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 { 213 Reference< XInvocation > xI = getDefaultInvocation(); 214 if( xI.is() ) 215 return xI->getIntrospection(); 216 return Reference< XIntrospectionAccess >(); 217 } 218 219 // XInvokation 220 Any SAL_CALL ResourceService::invoke 221 ( 222 const OUString& FunctionName, 223 const Sequence< Any >& Params, 224 Sequence< sal_Int16 >& OutParamIndex, 225 Sequence< Any >& OutParam 226 ) 227 { 228 Any aRet; 229 if( FunctionName.equalsAscii("getString") 230 || FunctionName.equalsAscii("getStrings" ) 231 || FunctionName.equalsAscii("hasString" ) 232 || FunctionName.equalsAscii("hasStrings" ) 233 ) 234 { 235 sal_Int32 nElements = Params.getLength(); 236 if( nElements < 1 ) 237 throw IllegalArgumentException(); 238 if( nElements > 1 && (FunctionName.equalsAscii("getString") || FunctionName.equalsAscii("hasString") ) ) 239 throw IllegalArgumentException(); 240 if( !pResMgr ) 241 throw IllegalArgumentException(); 242 243 Sequence< OUString > aStrings( Params.getLength() ); 244 Sequence< sal_Bool > aBools( Params.getLength() ); 245 const Any* pIn = Params.getConstArray(); 246 OUString* pOutString = aStrings.getArray(); 247 sal_Bool* pOutBool = aBools.getArray(); 248 249 Reference< XTypeConverter > xC = getTypeConverter(); 250 bool bGetBranch = FunctionName.equalsAscii( "getString" ) || FunctionName.equalsAscii( "getStrings" ); 251 252 OGuard aGuard( Application::GetSolarMutex() ); 253 for( sal_Int32 n = 0; n < nElements; n++ ) 254 { 255 sal_Int32 nId = 0; 256 if( !(pIn[n] >>= nId) ) 257 { 258 if( xC.is() ) 259 { 260 xC->convertToSimpleType( pIn[n], TypeClass_LONG ) >>= nId; 261 } 262 else 263 throw CannotConvertException(); 264 } 265 if( nId > 0xFFFF || nId < 0 ) 266 throw IllegalArgumentException(); 267 268 if( bGetBranch ) 269 { 270 ResId aId( (sal_uInt16)nId, *pResMgr ); 271 aId.SetRT( RSC_STRING ); 272 if( pResMgr->IsAvailable( aId ) ) 273 { 274 String aStr( aId ); 275 pOutString[n] = aStr; 276 } 277 else 278 throw IllegalArgumentException(); 279 } 280 else // hasString(s) 281 { 282 sal_Bool bRet = sal_False; 283 if( pResMgr ) 284 { 285 ResId aId( (sal_uInt16)nId, *pResMgr ); 286 aId.SetRT( RSC_STRING ); 287 bRet = pResMgr->IsAvailable( aId ); 288 } 289 pOutBool[n] = bRet; 290 } 291 } 292 if( FunctionName.equalsAscii("getString") ) 293 aRet <<= pOutString[0]; 294 else if( FunctionName.equalsAscii("getStrings" ) ) 295 aRet <<= aStrings; 296 else if( FunctionName.equalsAscii("hasString" ) ) 297 aRet <<= pOutBool[0]; 298 else 299 aRet <<= aBools; 300 } 301 else if( FunctionName.equalsAscii("getStringList") || FunctionName.equalsAscii("hasStringList" ) ) 302 { 303 if( Params.getLength() != 1 ) 304 throw IllegalArgumentException(); 305 Reference< XTypeConverter > xC = getTypeConverter(); 306 OGuard aGuard( Application::GetSolarMutex() ); 307 308 sal_Int32 nId = 0; 309 if( !(Params.getConstArray()[0] >>= nId) ) 310 { 311 if( xC.is() ) 312 { 313 xC->convertToSimpleType( Params.getConstArray()[0], TypeClass_LONG ) >>= nId; 314 } 315 else 316 throw CannotConvertException(); 317 } 318 319 if( FunctionName.equalsAscii("getStringList") ) 320 { 321 ResId aId( (sal_uInt16)nId, *pResMgr ); 322 aId.SetRT( RSC_STRINGARRAY ); 323 if( pResMgr->IsAvailable( aId ) ) 324 { 325 ResStringArray aStr( aId ); 326 int nEntries = aStr.Count(); 327 Sequence< PropertyValue > aPropSeq( nEntries ); 328 PropertyValue* pOut = aPropSeq.getArray(); 329 for( int i = 0; i < nEntries; i++ ) 330 { 331 pOut[i].Name = aStr.GetString( i ); 332 pOut[i].Handle = -1; 333 pOut[i].Value <<= aStr.GetValue( i ); 334 pOut[i].State = PropertyState_DIRECT_VALUE; 335 } 336 aRet <<= aPropSeq; 337 } 338 else 339 throw IllegalArgumentException(); 340 } 341 else // hasStringList 342 { 343 sal_Bool bRet = sal_False; 344 if( pResMgr ) 345 { 346 ResId aId( (sal_uInt16)nId, *pResMgr ); 347 aId.SetRT( RSC_STRINGARRAY ); 348 bRet = pResMgr->IsAvailable( aId ); 349 } 350 aRet <<= bRet; 351 } 352 } 353 else 354 { 355 Reference< XInvocation > xI = getDefaultInvocation(); 356 if( xI.is() ) 357 return xI->invoke( FunctionName, Params, OutParamIndex, OutParam ); 358 else 359 throw IllegalArgumentException(); 360 } 361 return aRet; 362 } 363 364 // XInvokation 365 void SAL_CALL ResourceService::setValue(const OUString& PropertyName, const Any& Value) 366 { 367 if( PropertyName.equalsAscii("FileName") ) 368 { 369 OUString aName; 370 if( !(Value >>= aName) ) 371 { 372 Reference< XTypeConverter > xC = getTypeConverter(); 373 if( xC.is() ) 374 xC->convertToSimpleType( Value, TypeClass_STRING ) >>= aName; 375 else 376 throw CannotConvertException(); 377 } 378 379 OGuard aGuard( Application::GetSolarMutex() ); 380 OStringBuffer aBuf( aName.getLength()+8 ); 381 aBuf.append( OUStringToOString( aName, osl_getThreadTextEncoding() ) ); 382 ResMgr * pRM = ResMgr::CreateResMgr( aBuf.getStr() ); 383 if( !pRM ) 384 throw InvocationTargetException(); 385 if( pResMgr ) 386 delete pResMgr; 387 pResMgr = pRM; 388 aFileName = OStringToOUString( aBuf.makeStringAndClear(), osl_getThreadTextEncoding() ); 389 } 390 else 391 { 392 Reference< XInvocation > xI = getDefaultInvocation(); 393 if( xI.is() ) 394 xI->setValue( PropertyName, Value ); 395 else 396 throw UnknownPropertyException(); 397 } 398 } 399 400 // XInvokation 401 Any SAL_CALL ResourceService::getValue(const OUString& PropertyName) 402 { 403 OGuard aGuard( Application::GetSolarMutex() ); 404 if( PropertyName.equalsAscii("FileName" )) 405 return makeAny( aFileName ); 406 407 Reference< XInvocation > xI = getDefaultInvocation(); 408 if( xI.is() ) 409 return xI->getValue( PropertyName ); 410 411 throw UnknownPropertyException(); 412 } 413 414 // XInvokation 415 sal_Bool SAL_CALL ResourceService::hasMethod(const OUString& Name) 416 { 417 if( Name.equalsAscii("getString") || 418 Name.equalsAscii("getStrings") || 419 Name.equalsAscii("hasString") || 420 Name.equalsAscii("hasStrings") || 421 Name.equalsAscii("getStringList") || 422 Name.equalsAscii("hasStringList") 423 ) 424 return sal_True; 425 else 426 { 427 Reference< XInvocation > xI = getDefaultInvocation(); 428 if( xI.is() ) 429 return xI->hasMethod( Name ); 430 else 431 return sal_False; 432 } 433 } 434 435 // XInvokation 436 sal_Bool SAL_CALL ResourceService::hasProperty(const OUString& Name) 437 { 438 if( Name.equalsAscii("FileName") ) 439 return sal_True; 440 else 441 { 442 Reference< XInvocation > xI = getDefaultInvocation(); 443 if( xI.is() ) 444 return xI->hasProperty( Name ); 445 else 446 return sal_False; 447 } 448 } 449 450 namespace res 451 { 452 ComponentInfo getComponentInfo_VclStringResourceLoader() 453 { 454 ComponentInfo aInfo; 455 aInfo.aSupportedServices = ResourceService::getSupportedServiceNames_Static(); 456 aInfo.sImplementationName = ResourceService::getImplementationName_Static(); 457 aInfo.pFactory = &ResourceService::Create; 458 return aInfo; 459 } 460 } 461