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();
getImplementationName_Static()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 //-----------------------------------------------------------------------------
ResourceService(const Reference<XMultiServiceFactory> & rSMgr)102 ResourceService::ResourceService( const Reference< XMultiServiceFactory > & rSMgr )
103 : xSMgr( rSMgr )
104 , pResMgr( NULL )
105 {
106 }
107
108 //-----------------------------------------------------------------------------
Create(const Reference<XComponentContext> & _rxContext)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 //-----------------------------------------------------------------------------
~ResourceService()116 ResourceService::~ResourceService()
117 {
118 delete pResMgr;
119 }
120
121 // XServiceInfo
getImplementationName()122 OUString ResourceService::getImplementationName() throw()
123 {
124 return getImplementationName_Static();
125 }
126
127 // XServiceInfo
supportsService(const OUString & ServiceName)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
getSupportedServiceNames(void)139 Sequence< OUString > SAL_CALL ResourceService::getSupportedServiceNames(void) throw()
140 {
141 return getSupportedServiceNames_Static();
142 }
143
144 // ResourceService
getSupportedServiceNames_Static(void)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
getTypeConverter() const153 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
getDefaultInvocation() const165 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
getExactName(const OUString & ApproximateName)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
getIntrospection(void)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
invoke(const OUString & FunctionName,const Sequence<Any> & Params,Sequence<sal_Int16> & OutParamIndex,Sequence<Any> & OutParam)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
setValue(const OUString & PropertyName,const Any & Value)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
getValue(const OUString & PropertyName)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
hasMethod(const OUString & Name)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
hasProperty(const OUString & Name)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 {
getComponentInfo_VclStringResourceLoader()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