| /************************************************************** |
| * |
| * 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; |
| } |
| } |
| |