xref: /trunk/main/extensions/source/resource/resource.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956) !
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 );
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 //-----------------------------------------------------------------------------
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 )
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 {
213     Reference< XInvocation > xI = getDefaultInvocation();
214     if( xI.is() )
215         return xI->getIntrospection();
216     return Reference< XIntrospectionAccess >();
217 }
218 
219 // XInvokation
invoke(const OUString & FunctionName,const Sequence<Any> & Params,Sequence<sal_Int16> & OutParamIndex,Sequence<Any> & OutParam)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
setValue(const OUString & PropertyName,const Any & Value)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
getValue(const OUString & PropertyName)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
hasMethod(const OUString & Name)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
hasProperty(const OUString & Name)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 {
getComponentInfo_VclStringResourceLoader()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