blob: c32f2055a6b0a141565593fa8129501a43ddff49 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "res_services.hxx"
#include <vos/mutex.hxx>
#include <uno/lbnames.h> // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/factory.hxx> // helper for factories
#include <cppuhelper/implbase3.hxx> // helper for implementations
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/reflection/InvocationTargetException.hpp>
#include <com/sun/star/beans/XExactName.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/PropertyState.hpp>
#include <tools/resmgr.hxx>
#include <tools/rcid.h>
#include <tools/resary.hxx>
#include <vcl/svapp.hxx>
#include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
using namespace vos;
using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;
using namespace com::sun::star::script;
using namespace com::sun::star::beans;
using namespace com::sun::star::reflection;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
class ResourceService : public cppu::WeakImplHelper3< XInvocation, XExactName, XServiceInfo >
{
public:
ResourceService( const Reference< XMultiServiceFactory > & );
~ResourceService();
// XServiceInfo
OUString SAL_CALL getImplementationName() throw();
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
static Sequence< OUString > getSupportedServiceNames_Static(void) throw();
static OUString getImplementationName_Static() throw()
{
return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.extensions.ResourceService"));
}
static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext );
// XExactName
OUString SAL_CALL getExactName( const OUString & ApproximateName ) throw(RuntimeException);
// XInvokation
Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(RuntimeException);
Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam) throw(IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
void SAL_CALL setValue(const OUString& PropertyName, const Any& Value) throw(UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
Any SAL_CALL getValue(const OUString& PropertyName) throw(UnknownPropertyException, RuntimeException);
sal_Bool SAL_CALL hasMethod(const OUString& Name) throw(RuntimeException);
sal_Bool SAL_CALL hasProperty(const OUString& Name) throw(RuntimeException);
private:
Reference< XTypeConverter > getTypeConverter() const;
Reference< XInvocation > getDefaultInvocation() const;
Reference< XMultiServiceFactory > xSMgr;
Reference< XInvocation > xDefaultInvocation;
Reference< XTypeConverter > xTypeConverter;
OUString aFileName;
ResMgr * pResMgr;
};
//-----------------------------------------------------------------------------
ResourceService::ResourceService( const Reference< XMultiServiceFactory > & rSMgr )
: xSMgr( rSMgr )
, pResMgr( NULL )
{
}
//-----------------------------------------------------------------------------
Reference< XInterface > ResourceService::Create( const Reference< XComponentContext >& _rxContext )
{
Reference< XMultiServiceFactory > xFactory( _rxContext->getServiceManager(), UNO_QUERY_THROW );
return *( new ResourceService( xFactory ) );
}
//-----------------------------------------------------------------------------
ResourceService::~ResourceService()
{
delete pResMgr;
}
// XServiceInfo
OUString ResourceService::getImplementationName() throw()
{
return getImplementationName_Static();
}
// XServiceInfo
sal_Bool SAL_CALL ResourceService::supportsService(const OUString& ServiceName) throw()
{
Sequence< OUString > aSNL = getSupportedServiceNames();
const OUString * pArray = aSNL.getConstArray();
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
if( pArray[i] == ServiceName )
return sal_True;
return sal_False;
}
// XServiceInfo
Sequence< OUString > SAL_CALL ResourceService::getSupportedServiceNames(void) throw()
{
return getSupportedServiceNames_Static();
}
// ResourceService
Sequence< OUString > ResourceService::getSupportedServiceNames_Static(void) throw()
{
Sequence< OUString > aSNS( 1 );
aSNS.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.VclStringResourceLoader"));
return aSNS;
}
// ResourceService
Reference< XTypeConverter > ResourceService::getTypeConverter() const
{
OGuard aGuard( Application::GetSolarMutex() );
if( xSMgr.is() )
{
Reference< XTypeConverter > xConv( xSMgr->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter" ))), UNO_QUERY );
((ResourceService*)this)->xTypeConverter = xConv;
}
return xTypeConverter;
}
// ResourceService
Reference< XInvocation > ResourceService::getDefaultInvocation() const
{
OGuard aGuard( Application::GetSolarMutex() );
/* f�hrt zur Zeit noch zu einer rekursion
if( xSMgr.is() )
{
Reference< XSingleServiceFactory > xFact( xSMgr->createInstance( OUString::createFromAscii("com.sun.star.script.Invocation") ), UNO_QUERY );
if( xFact.is() )
{
Sequence< Any > aArgs( 1 );
Reference< XInterface > xThis( *this );
aArgs.getArray()[0].set( &xThis, XInterface_Reference< get >lection() );
Reference< XInvokation > xI( xFact->createInstanceWithArguments( aArgs ), UNO_QUERY );
((ResourceService*)this)->xDefaultInvocation = xI;
}
}
*/
return xDefaultInvocation;
}
// XExactName
OUString SAL_CALL ResourceService::getExactName( const OUString & ApproximateName ) throw(RuntimeException)
{
OUString aName( ApproximateName );
aName = aName.toAsciiLowerCase();
if( aName.equalsAscii("filename") )
return OUString(RTL_CONSTASCII_USTRINGPARAM("FileName"));
else if( aName.equalsAscii("getstring" ))
return OUString(RTL_CONSTASCII_USTRINGPARAM("getString"));
else if( aName.equalsAscii("getstrings" ))
return OUString(RTL_CONSTASCII_USTRINGPARAM("getStrings"));
else if( aName.equalsAscii("hasstring") )
return OUString(RTL_CONSTASCII_USTRINGPARAM("hasString"));
else if( aName.equalsAscii("hasstrings") )
return OUString(RTL_CONSTASCII_USTRINGPARAM("hasStrings"));
else if( aName.equalsAscii("getstringlist") )
return OUString(RTL_CONSTASCII_USTRINGPARAM("getStringList"));
else if( aName.equalsAscii("hasStringList") )
return OUString(RTL_CONSTASCII_USTRINGPARAM("hasStringList"));
Reference< XExactName > xEN( getDefaultInvocation(), UNO_QUERY );
if( xEN.is() )
return xEN->getExactName( ApproximateName );
return OUString();
}
// XInvokation
Reference< XIntrospectionAccess > SAL_CALL ResourceService::getIntrospection(void)
throw(RuntimeException)
{
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
return xI->getIntrospection();
return Reference< XIntrospectionAccess >();
}
// XInvokation
Any SAL_CALL ResourceService::invoke
(
const OUString& FunctionName,
const Sequence< Any >& Params,
Sequence< sal_Int16 >& OutParamIndex,
Sequence< Any >& OutParam
)
throw(IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
{
Any aRet;
if( FunctionName.equalsAscii("getString")
|| FunctionName.equalsAscii("getStrings" )
|| FunctionName.equalsAscii("hasString" )
|| FunctionName.equalsAscii("hasStrings" )
)
{
sal_Int32 nElements = Params.getLength();
if( nElements < 1 )
throw IllegalArgumentException();
if( nElements > 1 && (FunctionName.equalsAscii("getString") || FunctionName.equalsAscii("hasString") ) )
throw IllegalArgumentException();
if( !pResMgr )
throw IllegalArgumentException();
Sequence< OUString > aStrings( Params.getLength() );
Sequence< sal_Bool > aBools( Params.getLength() );
const Any* pIn = Params.getConstArray();
OUString* pOutString = aStrings.getArray();
sal_Bool* pOutBool = aBools.getArray();
Reference< XTypeConverter > xC = getTypeConverter();
bool bGetBranch = FunctionName.equalsAscii( "getString" ) || FunctionName.equalsAscii( "getStrings" );
OGuard aGuard( Application::GetSolarMutex() );
for( sal_Int32 n = 0; n < nElements; n++ )
{
sal_Int32 nId = 0;
if( !(pIn[n] >>= nId) )
{
if( xC.is() )
{
xC->convertToSimpleType( pIn[n], TypeClass_LONG ) >>= nId;
}
else
throw CannotConvertException();
}
if( nId > 0xFFFF || nId < 0 )
throw IllegalArgumentException();
if( bGetBranch )
{
ResId aId( (sal_uInt16)nId, *pResMgr );
aId.SetRT( RSC_STRING );
if( pResMgr->IsAvailable( aId ) )
{
String aStr( aId );
pOutString[n] = aStr;
}
else
throw IllegalArgumentException();
}
else // hasString(s)
{
sal_Bool bRet = sal_False;
if( pResMgr )
{
ResId aId( (sal_uInt16)nId, *pResMgr );
aId.SetRT( RSC_STRING );
bRet = pResMgr->IsAvailable( aId );
}
pOutBool[n] = bRet;
}
}
if( FunctionName.equalsAscii("getString") )
aRet <<= pOutString[0];
else if( FunctionName.equalsAscii("getStrings" ) )
aRet <<= aStrings;
else if( FunctionName.equalsAscii("hasString" ) )
aRet <<= pOutBool[0];
else
aRet <<= aBools;
}
else if( FunctionName.equalsAscii("getStringList") || FunctionName.equalsAscii("hasStringList" ) )
{
if( Params.getLength() != 1 )
throw IllegalArgumentException();
Reference< XTypeConverter > xC = getTypeConverter();
OGuard aGuard( Application::GetSolarMutex() );
sal_Int32 nId = 0;
if( !(Params.getConstArray()[0] >>= nId) )
{
if( xC.is() )
{
xC->convertToSimpleType( Params.getConstArray()[0], TypeClass_LONG ) >>= nId;
}
else
throw CannotConvertException();
}
if( FunctionName.equalsAscii("getStringList") )
{
ResId aId( (sal_uInt16)nId, *pResMgr );
aId.SetRT( RSC_STRINGARRAY );
if( pResMgr->IsAvailable( aId ) )
{
ResStringArray aStr( aId );
int nEntries = aStr.Count();
Sequence< PropertyValue > aPropSeq( nEntries );
PropertyValue* pOut = aPropSeq.getArray();
for( int i = 0; i < nEntries; i++ )
{
pOut[i].Name = aStr.GetString( i );
pOut[i].Handle = -1;
pOut[i].Value <<= aStr.GetValue( i );
pOut[i].State = PropertyState_DIRECT_VALUE;
}
aRet <<= aPropSeq;
}
else
throw IllegalArgumentException();
}
else // hasStringList
{
sal_Bool bRet = sal_False;
if( pResMgr )
{
ResId aId( (sal_uInt16)nId, *pResMgr );
aId.SetRT( RSC_STRINGARRAY );
bRet = pResMgr->IsAvailable( aId );
}
aRet <<= bRet;
}
}
else
{
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
return xI->invoke( FunctionName, Params, OutParamIndex, OutParam );
else
throw IllegalArgumentException();
}
return aRet;
}
// XInvokation
void SAL_CALL ResourceService::setValue(const OUString& PropertyName, const Any& Value)
throw(UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
{
if( PropertyName.equalsAscii("FileName") )
{
OUString aName;
if( !(Value >>= aName) )
{
Reference< XTypeConverter > xC = getTypeConverter();
if( xC.is() )
xC->convertToSimpleType( Value, TypeClass_STRING ) >>= aName;
else
throw CannotConvertException();
}
OGuard aGuard( Application::GetSolarMutex() );
OStringBuffer aBuf( aName.getLength()+8 );
aBuf.append( OUStringToOString( aName, osl_getThreadTextEncoding() ) );
ResMgr * pRM = ResMgr::CreateResMgr( aBuf.getStr() );
if( !pRM )
throw InvocationTargetException();
if( pResMgr )
delete pResMgr;
pResMgr = pRM;
aFileName = OStringToOUString( aBuf.makeStringAndClear(), osl_getThreadTextEncoding() );
}
else
{
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
xI->setValue( PropertyName, Value );
else
throw UnknownPropertyException();
}
}
// XInvokation
Any SAL_CALL ResourceService::getValue(const OUString& PropertyName)
throw(UnknownPropertyException, RuntimeException)
{
OGuard aGuard( Application::GetSolarMutex() );
if( PropertyName.equalsAscii("FileName" ))
return makeAny( aFileName );
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
return xI->getValue( PropertyName );
throw UnknownPropertyException();
}
// XInvokation
sal_Bool SAL_CALL ResourceService::hasMethod(const OUString& Name)
throw(RuntimeException)
{
if( Name.equalsAscii("getString") ||
Name.equalsAscii("getStrings") ||
Name.equalsAscii("hasString") ||
Name.equalsAscii("hasStrings") ||
Name.equalsAscii("getStringList") ||
Name.equalsAscii("hasStringList")
)
return sal_True;
else
{
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
return xI->hasMethod( Name );
else
return sal_False;
}
}
// XInvokation
sal_Bool SAL_CALL ResourceService::hasProperty(const OUString& Name)
throw(RuntimeException)
{
if( Name.equalsAscii("FileName") )
return sal_True;
else
{
Reference< XInvocation > xI = getDefaultInvocation();
if( xI.is() )
return xI->hasProperty( Name );
else
return sal_False;
}
}
namespace res
{
ComponentInfo getComponentInfo_VclStringResourceLoader()
{
ComponentInfo aInfo;
aInfo.aSupportedServices = ResourceService::getSupportedServiceNames_Static();
aInfo.sImplementationName = ResourceService::getImplementationName_Static();
aInfo.pFactory = &ResourceService::Create;
return aInfo;
}
}