diff options
Diffstat (limited to 'scripting/source')
92 files changed, 23154 insertions, 0 deletions
diff --git a/scripting/source/basprov/baslibnode.cxx b/scripting/source/basprov/baslibnode.cxx new file mode 100644 index 000000000000..d955d75cca4a --- /dev/null +++ b/scripting/source/basprov/baslibnode.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "baslibnode.hxx" +#include "basmodnode.hxx" +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <basic/basmgr.hxx> +#include <basic/sbstar.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ============================================================================= + // BasicLibraryNodeImpl + // ============================================================================= + + BasicLibraryNodeImpl::BasicLibraryNodeImpl( const Reference< XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, BasicManager* pBasicManager, + const Reference< script::XLibraryContainer >& xLibContainer, const ::rtl::OUString& sLibName, bool isAppScript ) + :m_xContext( rxContext ) + ,m_sScriptingContext( sScriptingContext ) + ,m_pBasicManager( pBasicManager ) + ,m_xLibContainer( xLibContainer ) + ,m_sLibName( sLibName ) + ,m_bIsAppScript( isAppScript ) + { + if ( m_xLibContainer.is() ) + { + Any aElement = m_xLibContainer->getByName( m_sLibName ); + aElement >>= m_xLibrary; + } + } + + // ----------------------------------------------------------------------------- + + BasicLibraryNodeImpl::~BasicLibraryNodeImpl() + { + } + + // ----------------------------------------------------------------------------- + // XBrowseNode + // ----------------------------------------------------------------------------- + + ::rtl::OUString BasicLibraryNodeImpl::getName( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return m_sLibName; + } + + // ----------------------------------------------------------------------------- + + Sequence< Reference< browse::XBrowseNode > > BasicLibraryNodeImpl::getChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + Sequence< Reference< browse::XBrowseNode > > aChildNodes; + + if ( m_xLibContainer.is() && m_xLibContainer->hasByName( m_sLibName ) && !m_xLibContainer->isLibraryLoaded( m_sLibName ) ) + m_xLibContainer->loadLibrary( m_sLibName ); + + if ( m_pBasicManager ) + { + StarBASIC* pBasic = m_pBasicManager->GetLib( m_sLibName ); + if ( pBasic && m_xLibrary.is() ) + { + Sequence< ::rtl::OUString > aNames = m_xLibrary->getElementNames(); + sal_Int32 nCount = aNames.getLength(); + const ::rtl::OUString* pNames = aNames.getConstArray(); + aChildNodes.realloc( nCount ); + Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray(); + + for ( sal_Int32 i = 0 ; i < nCount ; ++i ) + { + SbModule* pModule = pBasic->FindModule( pNames[i] ); + if ( pModule ) + pChildNodes[i] = static_cast< browse::XBrowseNode* >( new BasicModuleNodeImpl( m_xContext, m_sScriptingContext, pModule, m_bIsAppScript ) ); + } + } + } + + return aChildNodes; + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicLibraryNodeImpl::hasChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_Bool bReturn = sal_False; + if ( m_xLibrary.is() ) + bReturn = m_xLibrary->hasElements(); + + return bReturn; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 BasicLibraryNodeImpl::getType( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return browse::BrowseNodeTypes::CONTAINER; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace basprov +//......................................................................... diff --git a/scripting/source/basprov/baslibnode.hxx b/scripting/source/basprov/baslibnode.hxx new file mode 100644 index 000000000000..8843f4121306 --- /dev/null +++ b/scripting/source/basprov/baslibnode.hxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BASLIBNODE_HXX +#define SCRIPTING_BASLIBNODE_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase1.hxx> + +class BasicManager; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ---------------------------------------------------- + // class BasicLibraryNodeImpl + // ---------------------------------------------------- + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::browse::XBrowseNode > BasicLibraryNodeImpl_BASE; + + + class BasicLibraryNodeImpl : public BasicLibraryNodeImpl_BASE + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::rtl::OUString m_sScriptingContext; + BasicManager* m_pBasicManager; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer > m_xLibContainer; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > m_xLibrary; + ::rtl::OUString m_sLibName; + bool m_bIsAppScript; + + public: + BasicLibraryNodeImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, + BasicManager* pBasicManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >& xLibContainer, + const ::rtl::OUString& sLibName, bool isAppScript=true ); + virtual ~BasicLibraryNodeImpl(); + + // XBrowseNode + virtual ::rtl::OUString SAL_CALL getName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getType( ) + throw (::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace basprov +//......................................................................... + +#endif // SCRIPTING_BASLIBNODE_HXX diff --git a/scripting/source/basprov/basmethnode.cxx b/scripting/source/basprov/basmethnode.cxx new file mode 100644 index 000000000000..f27b612ce9cb --- /dev/null +++ b/scripting/source/basprov/basmethnode.cxx @@ -0,0 +1,358 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "basmethnode.hxx" +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/XDispatchHelper.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <basic/sbstar.hxx> +#include <basic/sbmeth.hxx> +#include <basic/sbmod.hxx> + +#include <util/MiscUtils.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::comphelper; +using namespace ::com::sun::star::script; +using namespace ::sf_misc; + +#define BASPROV_PROPERTY_ID_URI 1 +#define BASPROV_PROPERTY_ID_EDITABLE 2 + +#define BASPROV_PROPERTY_URI ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URI" ) ) +#define BASPROV_PROPERTY_EDITABLE ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Editable" ) ) + +#define BASPROV_DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ============================================================================= + // BasicMethodNodeImpl + // ============================================================================= + + BasicMethodNodeImpl::BasicMethodNodeImpl( const Reference< XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, SbMethod* pMethod, bool isAppScript ) + : ::scripting_helper::OBroadcastHelperHolder( m_aMutex ) + ,OPropertyContainer( GetBroadcastHelper() ) + ,m_xContext( rxContext ) + ,m_sScriptingContext( sScriptingContext ) + ,m_pMethod( pMethod ) + ,m_bIsAppScript( isAppScript ) + ,m_bEditable( sal_True ) + { + if ( m_pMethod ) + { + SbModule* pModule = m_pMethod->GetModule(); + if ( pModule ) + { + StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() ); + if ( pBasic ) + { + m_sURI = ::rtl::OUString::createFromAscii( "vnd.sun.star.script:" ); + m_sURI += pBasic->GetName(); + m_sURI += ::rtl::OUString::createFromAscii( "." ); + m_sURI += pModule->GetName(); + m_sURI += ::rtl::OUString::createFromAscii( "." ); + m_sURI += m_pMethod->GetName(); + m_sURI += ::rtl::OUString::createFromAscii( "?language=Basic&location=" ); + if ( m_bIsAppScript ) + m_sURI += ::rtl::OUString::createFromAscii( "application" ); + else + m_sURI += ::rtl::OUString::createFromAscii( "document" ); + } + } + } + + registerProperty( BASPROV_PROPERTY_URI, BASPROV_PROPERTY_ID_URI, BASPROV_DEFAULT_ATTRIBS(), &m_sURI, ::getCppuType( &m_sURI ) ); + registerProperty( BASPROV_PROPERTY_EDITABLE, BASPROV_PROPERTY_ID_EDITABLE, BASPROV_DEFAULT_ATTRIBS(), &m_bEditable, ::getCppuType( &m_bEditable ) ); + } + + // ----------------------------------------------------------------------------- + + BasicMethodNodeImpl::~BasicMethodNodeImpl() + { + } + + // ----------------------------------------------------------------------------- + // XInterface + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XINTERFACE2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer ) + + // ----------------------------------------------------------------------------- + // XTypeProvider + // ----------------------------------------------------------------------------- + + IMPLEMENT_FORWARD_XTYPEPROVIDER2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer ) + + // ----------------------------------------------------------------------------- + // XBrowseNode + // ----------------------------------------------------------------------------- + + ::rtl::OUString BasicMethodNodeImpl::getName( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ::rtl::OUString sMethodName; + if ( m_pMethod ) + sMethodName = m_pMethod->GetName(); + + return sMethodName; + } + + // ----------------------------------------------------------------------------- + + Sequence< Reference< browse::XBrowseNode > > BasicMethodNodeImpl::getChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return Sequence< Reference< browse::XBrowseNode > >(); + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicMethodNodeImpl::hasChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return sal_False; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 BasicMethodNodeImpl::getType( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return browse::BrowseNodeTypes::SCRIPT; + } + + // ----------------------------------------------------------------------------- + // OPropertySetHelper + // ----------------------------------------------------------------------------- + + ::cppu::IPropertyArrayHelper& BasicMethodNodeImpl::getInfoHelper( ) + { + return *getArrayHelper(); + } + + // ----------------------------------------------------------------------------- + // OPropertyArrayUsageHelper + // ----------------------------------------------------------------------------- + + ::cppu::IPropertyArrayHelper* BasicMethodNodeImpl::createArrayHelper( ) const + { + Sequence< Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); + } + + // ----------------------------------------------------------------------------- + // XPropertySet + // ----------------------------------------------------------------------------- + + Reference< XPropertySetInfo > BasicMethodNodeImpl::getPropertySetInfo( ) throw (RuntimeException) + { + Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + // ----------------------------------------------------------------------------- + // XInvocation + // ----------------------------------------------------------------------------- + + Reference< XIntrospectionAccess > BasicMethodNodeImpl::getIntrospection( ) throw (RuntimeException) + { + return Reference< XIntrospectionAccess >(); + } + + // ----------------------------------------------------------------------------- + + Any BasicMethodNodeImpl::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, + Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) + throw (IllegalArgumentException, script::CannotConvertException, + reflection::InvocationTargetException, RuntimeException) + { + (void)aParams; + (void)aOutParamIndex; + (void)aOutParam; + + if ( aFunctionName == BASPROV_PROPERTY_EDITABLE ) + { + ::rtl::OUString sDocURL, sLibName, sModName; + USHORT nLine1 = 0, nLine2; + + if ( !m_bIsAppScript ) + { + Reference< frame::XModel > xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext ); + + if ( xModel.is() ) + { + sDocURL = xModel->getURL(); + if ( sDocURL.getLength() == 0 ) + { + Sequence < PropertyValue > aProps = xModel->getArgs(); + sal_Int32 nProps = aProps.getLength(); + const PropertyValue* pProps = aProps.getConstArray(); + for ( sal_Int32 i = 0; i < nProps; ++i ) + { + // TODO: according to MBA the property 'Title' may change in future + if ( pProps[i].Name == ::rtl::OUString::createFromAscii( "Title" ) ) + { + pProps[i].Value >>= sDocURL; + break; + } + } + } + } + } + + if ( m_pMethod ) + { + m_pMethod->GetLineRange( nLine1, nLine2 ); + SbModule* pModule = m_pMethod->GetModule(); + if ( pModule ) + { + sModName = pModule->GetName(); + StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() ); + if ( pBasic ) + sLibName = pBasic->GetName(); + } + } + + if ( m_xContext.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + + if ( xSMgr.is() ) + { + Reference< frame::XDesktop > xDesktop( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), m_xContext ), UNO_QUERY ); + + if ( xDesktop.is() ) + { + Reference < frame::XDispatchProvider > xProv( xDesktop->getCurrentFrame(), UNO_QUERY ); + + if ( xProv.is() ) + { + Reference< frame::XDispatchHelper > xHelper( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DispatchHelper" ) ), m_xContext ), UNO_QUERY ); + + if ( xHelper.is() ) + { + Sequence < PropertyValue > aArgs(7); + aArgs[0].Name = ::rtl::OUString::createFromAscii( "Document" ); + aArgs[0].Value <<= sDocURL; + aArgs[1].Name = ::rtl::OUString::createFromAscii( "LibName" ); + aArgs[1].Value <<= sLibName; + aArgs[2].Name = ::rtl::OUString::createFromAscii( "Name" ); + aArgs[2].Value <<= sModName; + aArgs[3].Name = ::rtl::OUString::createFromAscii( "Type" ); + aArgs[3].Value <<= ::rtl::OUString::createFromAscii( "Module" ); + aArgs[4].Name = ::rtl::OUString::createFromAscii( "Line" ); + aArgs[4].Value <<= static_cast< sal_uInt32 >( nLine1 ); + xHelper->executeDispatch( xProv, ::rtl::OUString::createFromAscii( ".uno:BasicIDEAppear" ), ::rtl::OUString(), 0, aArgs ); + } + } + } + } + } + } + else + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::invoke: function name not supported!" ) ), + Reference< XInterface >(), 1 ); + } + + return Any(); + } + + // ----------------------------------------------------------------------------- + + void BasicMethodNodeImpl::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) + throw (UnknownPropertyException, script::CannotConvertException, + reflection::InvocationTargetException, RuntimeException) + { + (void)aPropertyName; + (void)aValue; + + throw UnknownPropertyException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::setValue: property name is unknown!" ) ), + Reference< XInterface >() ); + } + + // ----------------------------------------------------------------------------- + + Any BasicMethodNodeImpl::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException) + { + (void)aPropertyName; + + throw UnknownPropertyException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::getValue: property name is unknown!" ) ), + Reference< XInterface >() ); + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicMethodNodeImpl::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException) + { + sal_Bool bReturn = sal_False; + if ( aName == BASPROV_PROPERTY_EDITABLE ) + bReturn = sal_True; + + return bReturn; + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicMethodNodeImpl::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException) + { + (void)aName; + + return sal_False; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace basprov +//......................................................................... diff --git a/scripting/source/basprov/basmethnode.hxx b/scripting/source/basprov/basmethnode.hxx new file mode 100644 index 000000000000..cd4f587c884f --- /dev/null +++ b/scripting/source/basprov/basmethnode.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BASMETHNODE_HXX +#define SCRIPTING_BASMETHNODE_HXX + +#include "bcholder.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <comphelper/proparrhlp.hxx> +#include <comphelper/propertycontainer.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase2.hxx> + + +class SbMethod; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ---------------------------------------------------- + // class BasicMethodNodeImpl + // ---------------------------------------------------- + + typedef ::cppu::WeakImplHelper2< + ::com::sun::star::script::browse::XBrowseNode, + ::com::sun::star::script::XInvocation > BasicMethodNodeImpl_BASE; + + class BasicMethodNodeImpl : public BasicMethodNodeImpl_BASE, + public ::scripting_helper::OMutexHolder, + public ::scripting_helper::OBroadcastHelperHolder, + public ::comphelper::OPropertyContainer, + public ::comphelper::OPropertyArrayUsageHelper< BasicMethodNodeImpl > + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::rtl::OUString m_sScriptingContext; + SbMethod* m_pMethod; + bool m_bIsAppScript; + + // properties + ::rtl::OUString m_sURI; + sal_Bool m_bEditable; + + protected: + // OPropertySetHelper + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( ); + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; + + public: + BasicMethodNodeImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, + SbMethod* pMethod, bool isAppScript = true ); + virtual ~BasicMethodNodeImpl(); + + // XInterface + DECLARE_XINTERFACE() + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // XBrowseNode + virtual ::rtl::OUString SAL_CALL getName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getType( ) + throw (::com::sun::star::uno::RuntimeException); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw (::com::sun::star::uno::RuntimeException); + + // XInvocation + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL invoke( + const ::rtl::OUString& aFunctionName, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, + ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex, + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::script::CannotConvertException, + ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::script::CannotConvertException, + ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) + throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace basprov +//......................................................................... + +#endif // SCRIPTING_BASMETHNODE_HXX diff --git a/scripting/source/basprov/basmodnode.cxx b/scripting/source/basprov/basmodnode.cxx new file mode 100644 index 000000000000..fe6ed69fccab --- /dev/null +++ b/scripting/source/basprov/basmodnode.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "basmodnode.hxx" +#include "basmethnode.hxx" +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <basic/sbx.hxx> +#include <basic/sbstar.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbmeth.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ============================================================================= + // BasicModuleNodeImpl + // ============================================================================= + + BasicModuleNodeImpl::BasicModuleNodeImpl( const Reference< XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, SbModule* pModule, bool isAppScript ) + :m_xContext( rxContext ) + ,m_sScriptingContext( sScriptingContext ) + ,m_pModule( pModule ) + ,m_bIsAppScript( isAppScript ) + { + } + + // ----------------------------------------------------------------------------- + + BasicModuleNodeImpl::~BasicModuleNodeImpl() + { + } + + // ----------------------------------------------------------------------------- + // XBrowseNode + // ----------------------------------------------------------------------------- + + ::rtl::OUString BasicModuleNodeImpl::getName( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + ::rtl::OUString sModuleName; + if ( m_pModule ) + sModuleName = m_pModule->GetName(); + + return sModuleName; + } + + // ----------------------------------------------------------------------------- + + Sequence< Reference< browse::XBrowseNode > > BasicModuleNodeImpl::getChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + Sequence< Reference< browse::XBrowseNode > > aChildNodes; + + if ( m_pModule ) + { + SbxArray* pMethods = m_pModule->GetMethods(); + if ( pMethods ) + { + sal_Int32 nCount = pMethods->Count(); + sal_Int32 nRealCount = 0; + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Get( static_cast< USHORT >( i ) ) ); + if ( pMethod && !pMethod->IsHidden() ) + ++nRealCount; + } + aChildNodes.realloc( nRealCount ); + Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray(); + + sal_Int32 iTarget = 0; + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Get( static_cast< USHORT >( i ) ) ); + if ( pMethod && !pMethod->IsHidden() ) + pChildNodes[iTarget++] = static_cast< browse::XBrowseNode* >( new BasicMethodNodeImpl( m_xContext, m_sScriptingContext, pMethod, m_bIsAppScript ) ); + } + } + } + + return aChildNodes; + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicModuleNodeImpl::hasChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_Bool bReturn = sal_False; + if ( m_pModule ) + { + SbxArray* pMethods = m_pModule->GetMethods(); + if ( pMethods && pMethods->Count() > 0 ) + bReturn = sal_True; + } + + return bReturn; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 BasicModuleNodeImpl::getType( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return browse::BrowseNodeTypes::CONTAINER; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace basprov +//......................................................................... diff --git a/scripting/source/basprov/basmodnode.hxx b/scripting/source/basprov/basmodnode.hxx new file mode 100644 index 000000000000..6f3ef3263e51 --- /dev/null +++ b/scripting/source/basprov/basmodnode.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BASMODNODE_HXX +#define SCRIPTING_BASMODNODE_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase1.hxx> + +class SbModule; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ---------------------------------------------------- + // class BasicModuleNodeImpl + // ---------------------------------------------------- + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::browse::XBrowseNode > BasicModuleNodeImpl_BASE; + + + class BasicModuleNodeImpl : public BasicModuleNodeImpl_BASE + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::rtl::OUString m_sScriptingContext; + SbModule* m_pModule; + bool m_bIsAppScript; + + public: + BasicModuleNodeImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, + const ::rtl::OUString& sScriptingContext, + SbModule* pModule, bool isAppScript = true ); + virtual ~BasicModuleNodeImpl(); + + // XBrowseNode + virtual ::rtl::OUString SAL_CALL getName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getType( ) + throw (::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace basprov +//......................................................................... + +#endif // SCRIPTING_BASMODNODE_HXX diff --git a/scripting/source/basprov/basprov.cxx b/scripting/source/basprov/basprov.cxx new file mode 100644 index 000000000000..69cc6f40cd3d --- /dev/null +++ b/scripting/source/basprov/basprov.cxx @@ -0,0 +1,606 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "basprov.hxx" +#include "basscript.hxx" +#include "baslibnode.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> + +#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ +#include <cppuhelper/implementationentry.hxx> +#endif +#include <rtl/uri.hxx> +#include <osl/process.h> +#include <osl/file.hxx> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <basic/sbx.hxx> +#include <basic/basmgr.hxx> +#include <basic/basicmanagerrepository.hxx> +#include <basic/sbstar.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbmeth.hxx> +#include <sfx2/app.hxx> +#include <sfx2/objsh.hxx> + +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/script/XLibraryContainer2.hpp> +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> + +#include <util/util.hxx> +#include <util/MiscUtils.hxx> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::document; +using namespace ::sf_misc; + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ============================================================================= + // component operations + // ============================================================================= + + static ::rtl::OUString getImplementationName_BasicProviderImpl() + { + static ::rtl::OUString* pImplName = 0; + if ( !pImplName ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pImplName ) + { + static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.ScriptProviderForBasic" ) ); + pImplName = &aImplName; + } + } + return *pImplName; + } + + // ----------------------------------------------------------------------------- + + static Sequence< ::rtl::OUString > getSupportedServiceNames_BasicProviderImpl() + { + static Sequence< ::rtl::OUString >* pNames = 0; + if ( !pNames ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pNames ) + { + static Sequence< ::rtl::OUString > aNames(4); + aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.ScriptProviderForBasic" ) ); + aNames.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.LanguageScriptProvider" ) ); + aNames.getArray()[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.ScriptProvider" ) ); + aNames.getArray()[3] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.browse.BrowseNode" ) ); + pNames = &aNames; + } + } + return *pNames; + } + + // ============================================================================= + // BasicProviderImpl + // ============================================================================= + + BasicProviderImpl::BasicProviderImpl( const Reference< XComponentContext >& xContext ) + :m_pAppBasicManager( 0 ) + ,m_pDocBasicManager( 0 ) + ,m_xLibContainerApp( 0 ) + ,m_xLibContainerDoc( 0 ) + ,m_xContext( xContext ) + ,m_bIsAppScriptCtx( true ) + ,m_bIsUserCtx(true) + { + } + + // ----------------------------------------------------------------------------- + + BasicProviderImpl::~BasicProviderImpl() + { + } + + // ----------------------------------------------------------------------------- + + bool BasicProviderImpl::isLibraryShared( const Reference< script::XLibraryContainer >& rxLibContainer, const ::rtl::OUString& rLibName ) + { + bool bIsShared = false; + + Reference< script::XLibraryContainer2 > xLibContainer( rxLibContainer, UNO_QUERY ); + if ( xLibContainer.is() && xLibContainer->hasByName( rLibName ) && xLibContainer->isLibraryLink( rLibName ) ) + { + ::rtl::OUString aFileURL; + if ( m_xContext.is() ) + { + Reference< uri::XUriReferenceFactory > xUriFac; + Reference< lang::XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + if ( xSMgr.is() ) + { + xUriFac.set( xSMgr->createInstanceWithContext( ::rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory" ), m_xContext ), UNO_QUERY ); + } + + if ( xUriFac.is() ) + { + ::rtl::OUString aLinkURL( xLibContainer->getLibraryLinkURL( rLibName ) ); + Reference< uri::XUriReference > xUriRef( xUriFac->parse( aLinkURL ), UNO_QUERY ); + + if ( xUriRef.is() ) + { + ::rtl::OUString aScheme = xUriRef->getScheme(); + if ( aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) + { + aFileURL = aLinkURL; + } + else if ( aScheme.equalsIgnoreAsciiCaseAscii( "vnd.sun.star.pkg" ) ) + { + ::rtl::OUString aAuthority = xUriRef->getAuthority(); + if ( aAuthority.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.expand:" ) ) ) + { + ::rtl::OUString aDecodedURL( aAuthority.copy( sizeof ( "vnd.sun.star.expand:" ) - 1 ) ); + aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); + Reference<util::XMacroExpander> xMacroExpander( + m_xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), + UNO_QUERY ); + if ( xMacroExpander.is() ) + aFileURL = xMacroExpander->expandMacros( aDecodedURL ); + } + } + } + } + } + + if ( aFileURL.getLength() ) + { + osl::DirectoryItem aFileItem; + osl::FileStatus aFileStatus( FileStatusMask_FileURL ); + OSL_VERIFY( osl::DirectoryItem::get( aFileURL, aFileItem ) == osl::FileBase::E_None ); + OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None ); + ::rtl::OUString aCanonicalFileURL( aFileStatus.getFileURL() ); + + ::rtl::OUString aSearchURL1( RTL_CONSTASCII_USTRINGPARAM( "share/basic" ) ); + ::rtl::OUString aSearchURL2( RTL_CONSTASCII_USTRINGPARAM( "share/uno_packages" ) ); + if( aCanonicalFileURL.indexOf( aSearchURL1 ) != -1 || aCanonicalFileURL.indexOf( aSearchURL2 ) != -1 ) + bIsShared = true; + } + } + + return bIsShared; + } + + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + + ::rtl::OUString BasicProviderImpl::getImplementationName( ) throw (RuntimeException) + { + return getImplementationName_BasicProviderImpl(); + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicProviderImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; + } + + // ----------------------------------------------------------------------------- + + Sequence< ::rtl::OUString > BasicProviderImpl::getSupportedServiceNames( ) throw (RuntimeException) + { + return getSupportedServiceNames_BasicProviderImpl(); + } + + // ----------------------------------------------------------------------------- + // XInitialization + // ----------------------------------------------------------------------------- + + void BasicProviderImpl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) + { + // TODO + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + if ( aArguments.getLength() != 1 ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: incorrect argument count." ) ), + *this, + 1 + ); + } + + Reference< frame::XModel > xModel; + + m_xInvocationContext.set( aArguments[0], UNO_QUERY );; + if ( m_xInvocationContext.is() ) + { + xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY ); + if ( !xModel.is() ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: unable to determine the document model from the script invocation context." ) ), + *this, + 1 + ); + } + } + else + { + if ( !( aArguments[0] >>= m_sScriptingContext ) ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: incorrect argument type " ) ).concat( aArguments[0].getValueTypeName() ), + *this, + 1 + ); + } + + ::rtl::OUString sDoc = OUSTR("vnd.sun.star.tdoc"); + if ( m_sScriptingContext.indexOf( sDoc ) == 0 ) + { + xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext ); + // TODO: use ScriptingContantsPool for SCRIPTING_DOC_REF + } + } + + if ( xModel.is() ) + { + Reference< XEmbeddedScripts > xDocumentScripts( xModel, UNO_QUERY ); + if ( xDocumentScripts.is() ) + { + m_pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( xModel ); + m_xLibContainerDoc.set( xDocumentScripts->getBasicLibraries(), UNO_QUERY ); + OSL_ENSURE( m_pDocBasicManager && m_xLibContainerDoc.is(), + "BasicProviderImpl::initialize: invalid BasicManager, or invalid script container!" ); + } + m_bIsAppScriptCtx = false; + } + else + { + // Provider has been created with application context for user + // or share + if ( !m_sScriptingContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "user" ) ) ) + { + m_bIsUserCtx = false; + } + else + { + /* + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: no scripting context!" ) ), + Reference< XInterface >() ); + */ + } + } + + // TODO + if ( !m_pAppBasicManager ) + m_pAppBasicManager = SFX_APP()->GetBasicManager(); + + if ( !m_xLibContainerApp.is() ) + m_xLibContainerApp = Reference< script::XLibraryContainer >( SFX_APP()->GetBasicContainer(), UNO_QUERY ); + } + + // ----------------------------------------------------------------------------- + + // XScriptProvider + // ----------------------------------------------------------------------------- + + Reference < provider::XScript > BasicProviderImpl::getScript( const ::rtl::OUString& scriptURI ) + throw ( provider::ScriptFrameworkErrorException, RuntimeException) + { + // TODO + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + Reference< provider::XScript > xScript; + Reference< lang::XMultiComponentFactory > xMcFac ( m_xContext->getServiceManager() ); + Reference< uri::XUriReferenceFactory > xFac ( + xMcFac->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); + + if ( !xFac.is() ) + { + throw provider::ScriptFrameworkErrorException( + OUSTR( "Failed to instantiate UriReferenceFactory" ), Reference< XInterface >(), + scriptURI, OUSTR("Basic"), + provider::ScriptFrameworkErrorType::UNKNOWN ); + } + + Reference< uri::XUriReference > uriRef( + xFac->parse( scriptURI ), UNO_QUERY ); + + Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY ); + + if ( !uriRef.is() || !sfUri.is() ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "BasicProviderImpl::getScript: failed to parse URI: " ); + errorMsg = errorMsg.concat( scriptURI ); + throw provider::ScriptFrameworkErrorException( + errorMsg, Reference< XInterface >(), + scriptURI, OUSTR("Basic"), + provider::ScriptFrameworkErrorType::MALFORMED_URL ); + } + + + ::rtl::OUString aDescription = sfUri->getName(); + ::rtl::OUString aLocation = sfUri->getParameter( + ::rtl::OUString::createFromAscii( "location" ) ); + + sal_Int32 nIndex = 0; + ::rtl::OUString aLibrary = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); + ::rtl::OUString aModule; + if ( nIndex != -1 ) + aModule = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); + ::rtl::OUString aMethod; + if ( nIndex != -1 ) + aMethod = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); + + if ( aLibrary.getLength() != 0 && aModule.getLength() != 0 && aMethod.getLength() != 0 && aLocation.getLength() != 0 ) + { + BasicManager* pBasicMgr = NULL; + if ( aLocation.equals( ::rtl::OUString::createFromAscii("document") ) ) + { + pBasicMgr = m_pDocBasicManager; + } + else if ( aLocation.equals( ::rtl::OUString::createFromAscii("application") ) ) + { + pBasicMgr = m_pAppBasicManager; + } + + if ( pBasicMgr ) + { + StarBASIC* pBasic = pBasicMgr->GetLib( aLibrary ); + if ( !pBasic ) + { + USHORT nId = pBasicMgr->GetLibId( aLibrary ); + if ( nId != LIB_NOTFOUND ) + { + pBasicMgr->LoadLib( nId ); + pBasic = pBasicMgr->GetLib( aLibrary ); + } + } + if ( pBasic ) + { + SbModule* pModule = pBasic->FindModule( aModule ); + if ( pModule ) + { + SbxArray* pMethods = pModule->GetMethods(); + if ( pMethods ) + { + SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Find( aMethod, SbxCLASS_METHOD ) ); + if ( pMethod && !pMethod->IsHidden() ) + { + if ( m_pDocBasicManager == pBasicMgr ) + xScript = new BasicScriptImpl( aDescription, pMethod, *m_pDocBasicManager, m_xInvocationContext ); + else + xScript = new BasicScriptImpl( aDescription, pMethod ); + } + } + } + } + } + } + + if ( !xScript.is() ) + { + ::rtl::OUStringBuffer aMessage; + aMessage.appendAscii( "The following Basic script could not be found:\n" ); + aMessage.appendAscii( "library: '" ).append( aLibrary ).appendAscii( "'\n" ); + aMessage.appendAscii( "module: '" ).append( aModule ).appendAscii( "'\n" ); + aMessage.appendAscii( "method: '" ).append( aMethod ).appendAscii( "'\n" ); + aMessage.appendAscii( "location: '" ).append( aLocation ).appendAscii( "'\n" ); + throw provider::ScriptFrameworkErrorException( + aMessage.makeStringAndClear(), + Reference< XInterface >(), + scriptURI, OUSTR("Basic"), + provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT ); + } + + return xScript; + } + + // ----------------------------------------------------------------------------- + // XBrowseNode + // ----------------------------------------------------------------------------- + + ::rtl::OUString BasicProviderImpl::getName( ) throw (RuntimeException) + { + // TODO + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return ::rtl::OUString::createFromAscii( "Basic" ); + } + + // ----------------------------------------------------------------------------- + + Sequence< Reference< browse::XBrowseNode > > BasicProviderImpl::getChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + Reference< script::XLibraryContainer > xLibContainer; + BasicManager* pBasicManager = NULL; + + if ( m_bIsAppScriptCtx ) + { + xLibContainer = m_xLibContainerApp; + pBasicManager = m_pAppBasicManager; + } + else + { + xLibContainer = m_xLibContainerDoc; + pBasicManager = m_pDocBasicManager; + } + + Sequence< Reference< browse::XBrowseNode > > aChildNodes; + + if ( pBasicManager && xLibContainer.is() ) + { + Sequence< ::rtl::OUString > aLibNames = xLibContainer->getElementNames(); + sal_Int32 nLibCount = aLibNames.getLength(); + const ::rtl::OUString* pLibNames = aLibNames.getConstArray(); + aChildNodes.realloc( nLibCount ); + Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray(); + sal_Int32 childsFound = 0; + + for ( sal_Int32 i = 0 ; i < nLibCount ; ++i ) + { + bool bCreate = false; + if ( m_bIsAppScriptCtx ) + { + bool bShared = isLibraryShared( xLibContainer, pLibNames[i] ); + if ( ( m_bIsUserCtx && !bShared ) || ( !m_bIsUserCtx && bShared ) ) + bCreate = true; + } + else + { + bCreate = true; + } + if ( bCreate ) + { + pChildNodes[childsFound++] = static_cast< browse::XBrowseNode* >( new BasicLibraryNodeImpl( + m_xContext, m_sScriptingContext, pBasicManager, xLibContainer, pLibNames[i], m_bIsAppScriptCtx ) ); + } + } + + if ( childsFound != nLibCount ) + aChildNodes.realloc( childsFound ); + } + + return aChildNodes; + } + + // ----------------------------------------------------------------------------- + + sal_Bool BasicProviderImpl::hasChildNodes( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_Bool bReturn = sal_False; + Reference< script::XLibraryContainer > xLibContainer; + if ( m_bIsAppScriptCtx ) + { + xLibContainer = m_xLibContainerApp; + } + else + { + xLibContainer = m_xLibContainerDoc; + } + if ( xLibContainer.is() ) + bReturn = xLibContainer->hasElements(); + + return bReturn; + } + + // ----------------------------------------------------------------------------- + + sal_Int16 BasicProviderImpl::getType( ) throw (RuntimeException) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return browse::BrowseNodeTypes::CONTAINER; + } + + // ============================================================================= + // component operations + // ============================================================================= + + static Reference< XInterface > SAL_CALL create_BasicProviderImpl( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) + { + return static_cast< lang::XTypeProvider * >( new BasicProviderImpl( xContext ) ); + } + + // ----------------------------------------------------------------------------- + + static struct ::cppu::ImplementationEntry s_component_entries [] = + { + { + create_BasicProviderImpl, getImplementationName_BasicProviderImpl, + getSupportedServiceNames_BasicProviderImpl, ::cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace basprov +//......................................................................... + + +// ============================================================================= +// component exports +// ============================================================================= + +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) + { + (void)ppEnv; + + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_writeInfoHelper( + pServiceManager, pRegistryKey, ::basprov::s_component_entries ); + } + + SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, ::basprov::s_component_entries ); + } +} diff --git a/scripting/source/basprov/basprov.hxx b/scripting/source/basprov/basprov.hxx new file mode 100644 index 000000000000..6cef4488fb43 --- /dev/null +++ b/scripting/source/basprov/basprov.hxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BASPROV_HXX +#define SCRIPTING_BASPROV_HXX + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/script/provider/XScriptProvider.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase4.hxx> + +class BasicManager; + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ---------------------------------------------------- + // class BasicProviderImpl + // ---------------------------------------------------- + + typedef ::cppu::WeakImplHelper4< + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::script::provider::XScriptProvider, + ::com::sun::star::script::browse::XBrowseNode > BasicProviderImpl_BASE; + + + class BasicProviderImpl : public BasicProviderImpl_BASE + { + private: + BasicManager* m_pAppBasicManager; + BasicManager* m_pDocBasicManager; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer > m_xLibContainerApp; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer > m_xLibContainerDoc; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::document::XScriptInvocationContext > m_xInvocationContext; + ::rtl::OUString m_sScriptingContext; + bool m_bIsAppScriptCtx; + bool m_bIsUserCtx; + ::rtl::OUString m_sCtxLocation; + + bool isLibraryShared( + const ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >& rxLibContainer, + const ::rtl::OUString& rLibName ); + + public: + BasicProviderImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); + virtual ~BasicProviderImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XScriptProvider + virtual ::com::sun::star::uno::Reference < ::com::sun::star::script::provider::XScript > SAL_CALL getScript( + const ::rtl::OUString& scriptURI ) + throw ( ::com::sun::star::script::provider::ScriptFrameworkErrorException, ::com::sun::star::uno::RuntimeException); + + // XBrowseNode + virtual ::rtl::OUString SAL_CALL getName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasChildNodes( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getType( ) + throw (::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace basprov +//......................................................................... + +#endif // SCRIPTING_BASPROV_HXX diff --git a/scripting/source/basprov/basprov.xml b/scripting/source/basprov/basprov.xml new file mode 100644 index 000000000000..0ae341cce157 --- /dev/null +++ b/scripting/source/basprov/basprov.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name>basprov</module-name> + + <component-description> + <author>Thomas Benisch</author> + <name>com.sun.star.comp.scripting.ScriptProviderForBasic</name> + <description>script provider for Basic</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="drafts"/> + <supported-service>com.sun.star.script.provider.ScriptProviderForBasic</supported-service> + <type>com.sun.star.beans.XPropertySet</type> + <type>com.sun.star.frame.XModel</type> + <type>com.sun.star.lang.IllegalArgumentException</type> + <type>com.sun.star.lang.XInitialization</type> + <type>com.sun.star.lang.XServiceInfo</type> + <type>com.sun.star.reflection.InvocationTargetException</type> + <type>com.sun.star.script.CannotConvertException</type> + <type>com.sun.star.uno.Exception</type> + <type>com.sun.star.uno.RuntimeException</type> + <type>com.sun.star.uno.XComponentContext</type> + <type>com.sun.star.script.browse.BrowseNodeTypes</type> + <type>com.sun.star.script.browse.XBrowseNode</type> + <type>com.sun.star.script.provider.XScript</type> + <type>com.sun.star.script.provider.XScriptProvider</type> + <type> com.sun.star.uri.XUriReference </type> + <type> com.sun.star.uri.XUriReferenceFactory </type> + <type> com.sun.star.uri.XVndSunStarScriptUrl </type> + </component-description> + + <project-build-dependency>sfx2</project-build-dependency> + <project-build-dependency>basic</project-build-dependency> + <project-build-dependency>svtools</project-build-dependency> + <project-build-dependency>tools</project-build-dependency> + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + + <runtime-module-dependency>sfx2</runtime-module-dependency> + <runtime-module-dependency>sb</runtime-module-dependency> + <runtime-module-dependency>svt</runtime-module-dependency> + <runtime-module-dependency>tl</runtime-module-dependency> + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> + +</module-description> diff --git a/scripting/source/basprov/basscript.cxx b/scripting/source/basprov/basscript.cxx new file mode 100644 index 000000000000..c6de155e3ed0 --- /dev/null +++ b/scripting/source/basprov/basscript.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "basscript.hxx" +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <basic/sbx.hxx> +#include <basic/sbstar.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbmeth.hxx> +#include <basic/basmgr.hxx> +#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> + +#include <map> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::document; + +extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar ); +extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); + + +//......................................................................... +namespace basprov +{ +//......................................................................... + + typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap; + + // ============================================================================= + // BasicScriptImpl + // ============================================================================= + + // ----------------------------------------------------------------------------- + + BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod ) + :m_xMethod( xMethod ) + ,m_funcName( funcName ) + ,m_documentBasicManager( NULL ) + ,m_xDocumentScriptContext() + { + } + + // ----------------------------------------------------------------------------- + + BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod, + BasicManager& documentBasicManager, const Reference< XScriptInvocationContext >& documentScriptContext ) + :m_xMethod( xMethod ) + ,m_funcName( funcName ) + ,m_documentBasicManager( &documentBasicManager ) + ,m_xDocumentScriptContext( documentScriptContext ) + { + } + + // ----------------------------------------------------------------------------- + BasicScriptImpl::~BasicScriptImpl() + { + } + + // ----------------------------------------------------------------------------- + // XScript + // ----------------------------------------------------------------------------- + + Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) + throw ( provider::ScriptFrameworkErrorException, reflection::InvocationTargetException, uno::RuntimeException) + { + // TODO: throw CannotConvertException + // TODO: check length of aOutParamIndex, aOutParam + + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + Any aReturn; + + if ( m_xMethod ) + { + // check if compiled + SbModule* pModule = static_cast< SbModule* >( m_xMethod->GetParent() ); + if ( pModule && !pModule->IsCompiled() ) + pModule->Compile(); + + // check number of parameters + sal_Int32 nParamsCount = aParams.getLength(); + SbxInfo* pInfo = m_xMethod->GetInfo(); + if ( pInfo ) + { + sal_Int32 nSbxOptional = 0; + USHORT n = 1; + for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) ) + { + if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 ) + ++nSbxOptional; + else + nSbxOptional = 0; + } + sal_Int32 nSbxCount = n - 1; + if ( nParamsCount < nSbxCount - nSbxOptional ) + { + throw provider::ScriptFrameworkErrorException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "wrong number of parameters!" ) ), + Reference< XInterface >(), + m_funcName, + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ), + provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT ); + } + } + + // set parameters + SbxArrayRef xSbxParams; + if ( nParamsCount > 0 ) + { + xSbxParams = new SbxArray; + const Any* pParams = aParams.getConstArray(); + for ( sal_Int32 i = 0; i < nParamsCount; ++i ) + { + SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT ); + unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] ); + xSbxParams->Put( xSbxVar, static_cast< USHORT >( i ) + 1 ); + + // Enable passing by ref + if ( xSbxVar->GetType() != SbxVARIANT ) + xSbxVar->SetFlag( SBX_FIXED ); + } + } + if ( xSbxParams.Is() ) + m_xMethod->SetParameters( xSbxParams ); + + // call method + SbxVariableRef xReturn = new SbxVariable; + ErrCode nErr = SbxERR_OK; + { + // if it's a document-based script, temporarily reset ThisComponent to the script invocation context + Any aOldThisComponent; + if ( m_documentBasicManager && m_xDocumentScriptContext.is() ) + aOldThisComponent = m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", makeAny( m_xDocumentScriptContext ) ); + + nErr = m_xMethod->Call( xReturn ); + + if ( m_documentBasicManager && m_xDocumentScriptContext.is() ) + m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent ); + } + if ( nErr != SbxERR_OK ) + { + // TODO: throw InvocationTargetException ? + } + + // get output parameters + if ( xSbxParams.Is() ) + { + SbxInfo* pInfo_ = m_xMethod->GetInfo(); + if ( pInfo_ ) + { + OutParamMap aOutParamMap; + for ( USHORT n = 1, nCount = xSbxParams->Count(); n < nCount; ++n ) + { + const SbxParamInfo* pParamInfo = pInfo_->GetParam( n ); + if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 ) + { + SbxVariable* pVar = xSbxParams->Get( n ); + if ( pVar ) + { + SbxVariableRef xVar = pVar; + aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) ); + } + } + } + sal_Int32 nOutParamCount = aOutParamMap.size(); + aOutParamIndex.realloc( nOutParamCount ); + aOutParam.realloc( nOutParamCount ); + sal_Int16* pOutParamIndex = aOutParamIndex.getArray(); + Any* pOutParam = aOutParam.getArray(); + for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam ) + { + *pOutParamIndex = aIt->first; + *pOutParam = aIt->second; + } + } + } + + // get return value + aReturn = sbxToUnoValue( xReturn ); + + // reset parameters + m_xMethod->SetParameters( NULL ); + } + + return aReturn; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace basprov +//......................................................................... diff --git a/scripting/source/basprov/basscript.hxx b/scripting/source/basprov/basscript.hxx new file mode 100644 index 000000000000..4a3d6f1ab61d --- /dev/null +++ b/scripting/source/basprov/basscript.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BASSCRIPT_HXX +#define SCRIPTING_BASSCRIPT_HXX + +#include <com/sun/star/script/provider/XScript.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> +#include <cppuhelper/implbase1.hxx> +#include <basic/sbmeth.hxx> + + +class BasicManager; + +//......................................................................... +namespace basprov +{ +//......................................................................... + + // ---------------------------------------------------- + // class BasicScriptImpl + // ---------------------------------------------------- + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::provider::XScript > BasicScriptImpl_BASE; + + + class BasicScriptImpl : public BasicScriptImpl_BASE + { + private: + SbMethodRef m_xMethod; + ::rtl::OUString m_funcName; + BasicManager* m_documentBasicManager; + ::com::sun::star::uno::Reference< ::com::sun::star::document::XScriptInvocationContext > + m_xDocumentScriptContext; + + public: + BasicScriptImpl( + const ::rtl::OUString& funcName, + SbMethodRef xMethod + ); + BasicScriptImpl( + const ::rtl::OUString& funcName, + SbMethodRef xMethod, + BasicManager& documentBasicManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::document::XScriptInvocationContext >& documentScriptContext + ); + virtual ~BasicScriptImpl(); + + // XScript + virtual ::com::sun::star::uno::Any SAL_CALL invoke( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, + ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex, + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) + throw ( + ::com::sun::star::script::provider::ScriptFrameworkErrorException, + ::com::sun::star::reflection::InvocationTargetException, + ::com::sun::star::uno::RuntimeException ); + }; + +//......................................................................... +} // namespace basprov +//......................................................................... + +#endif // SCRIPTING_BASSCRIPT_HXX diff --git a/scripting/source/basprov/makefile.mk b/scripting/source/basprov/makefile.mk new file mode 100644 index 000000000000..5001e5db288e --- /dev/null +++ b/scripting/source/basprov/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=scripting +TARGET=basprov +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/basprov.obj \ + $(SLO)$/basscript.obj \ + $(SLO)$/baslibnode.obj \ + $(SLO)$/basmodnode.obj \ + $(SLO)$/basmethnode.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX).uno +SHL1IMPLIB= i$(TARGET) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +SHL1STDLIBS= \ + $(SFX2LIB) \ + $(BASICLIB) \ + $(VCLLIB) \ + $(TOOLSLIB) \ + $(UCBHELPERLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/dlgprov/dlgevtatt.cxx b/scripting/source/dlgprov/dlgevtatt.cxx new file mode 100644 index 000000000000..6c3694ea237d --- /dev/null +++ b/scripting/source/dlgprov/dlgevtatt.cxx @@ -0,0 +1,679 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "dlgevtatt.hxx" + +#include "dlgprov.hxx" + +#include <sfx2/sfx.hrc> +#include <sfx2/app.hxx> +#include <vcl/msgbox.hxx> +#include <tools/diagnose_ex.h> + +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XDialogEventHandler.hpp> +#include <com/sun/star/awt/XContainerWindowEventHandler.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/XScriptEventsSupplier.hpp> +#include <com/sun/star/script/provider/XScriptProvider.hpp> +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp> +#include <com/sun/star/lang/NoSuchMethodException.hpp> +#include <com/sun/star/reflection/XIdlMethod.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> + +#include <ooo/vba/XVBAToOOEventDescGen.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <vbahelper/vbaaccesshelper.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::reflection; + + +//......................................................................... +namespace dlgprov +{ + + class DialogSFScriptListenerImpl : public DialogScriptListenerImpl + { + protected: + Reference< frame::XModel > m_xModel; + virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ); + public: + DialogSFScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogScriptListenerImpl( rxContext ), m_xModel( rxModel ) {} + }; + + class DialogLegacyScriptListenerImpl : public DialogSFScriptListenerImpl + { + protected: + virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ); + public: + DialogLegacyScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogSFScriptListenerImpl( rxContext, rxModel ){} + }; + + class DialogUnoScriptListenerImpl : public DialogSFScriptListenerImpl + { + Reference< awt::XControl > m_xControl; + Reference< XInterface > m_xHandler; + Reference< beans::XIntrospectionAccess > m_xIntrospectionAccess; + bool m_bDialogProviderMode; + + virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ); + + public: + DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext, + const Reference< frame::XModel >& rxModel, + const Reference< awt::XControl >& rxControl, + const Reference< XInterface >& rxHandler, + const Reference< beans::XIntrospectionAccess >& rxIntrospectionAccess, + bool bDialogProviderMode ); // false: ContainerWindowProvider mode + + }; + + class DialogVBAScriptListenerImpl : public DialogScriptListenerImpl + { + protected: + rtl::OUString msDialogCodeName; + Reference< script::XScriptListener > mxListener; + virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ); + public: + DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel ); + }; + + DialogVBAScriptListenerImpl::DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel ) : DialogScriptListenerImpl( rxContext ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + Sequence< Any > args(1); + if ( xSMgr.is() ) + { + args[0] <<= xModel; + mxListener = Reference< XScriptListener >( xSMgr->createInstanceWithArgumentsAndContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.EventListener" ) ), args, m_xContext ), UNO_QUERY ); + } + if ( rxControl.is() ) + { + try + { + Reference< XPropertySet > xProps( rxControl->getModel(), UNO_QUERY_THROW ); + xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= msDialogCodeName; + xProps.set( mxListener, UNO_QUERY_THROW ); + xProps->setPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ), args[ 0 ] ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + } + + void DialogVBAScriptListenerImpl::firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* ) + { + if ( aScriptEvent.ScriptType.equals( rtl::OUString::createFromAscii("VBAInterop") ) && mxListener.is() ) + { + ScriptEvent aScriptEventCopy( aScriptEvent ); + aScriptEventCopy.ScriptCode = msDialogCodeName; + try + { + mxListener->firing( aScriptEventCopy ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + +//......................................................................... + + // ============================================================================= + // DialogEventsAttacherImpl + // ============================================================================= + + DialogEventsAttacherImpl::DialogEventsAttacherImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel, const Reference< awt::XControl >& rxControl, const Reference< XInterface >& rxHandler, const Reference< beans::XIntrospectionAccess >& rxIntrospect, bool bProviderMode, const Reference< script::XScriptListener >& rxRTLListener ) + :mbUseFakeVBAEvents( false ), m_xContext( rxContext ) + { + // key listeners by protocol when ScriptType = 'Script' + // otherwise key is the ScriptType e.g. StarBasic + if ( rxRTLListener.is() ) // set up handler for RTL_BASIC + listernersForTypes[ rtl::OUString::createFromAscii("StarBasic") ] = rxRTLListener; + else + listernersForTypes[ rtl::OUString::createFromAscii("StarBasic") ] = new DialogLegacyScriptListenerImpl( rxContext, rxModel ); + // handler for Script & ::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" ) + listernersForTypes[ rtl::OUString::createFromAscii("vnd.sun.star.UNO") ] = new DialogUnoScriptListenerImpl( rxContext, rxModel, rxControl, rxHandler, rxIntrospect, bProviderMode ); + listernersForTypes[ rtl::OUString::createFromAscii("vnd.sun.star.script") ] = new DialogSFScriptListenerImpl( rxContext, rxModel ); + // Note: in a future cws ( npower13_ObjectModule ) it will be possible + // to determine the vba mode from the basiclibrary container, the tunnel hack + // below can then be replaced + SfxObjectShell* pFoundShell = NULL; + if ( rxModel.is() ) + { + uno::Reference< lang::XUnoTunnel > xObjShellTunnel( rxModel, uno::UNO_QUERY ); + if ( xObjShellTunnel.is() ) + { + pFoundShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId())); + if ( pFoundShell ) + mbUseFakeVBAEvents = ooo::vba::isAlienExcelDoc( *pFoundShell ); + } + } + if ( mbUseFakeVBAEvents ) + listernersForTypes[ rtl::OUString::createFromAscii("VBAInterop") ] = new DialogVBAScriptListenerImpl( rxContext, rxControl, rxModel ); + } + + // ----------------------------------------------------------------------------- + + DialogEventsAttacherImpl::~DialogEventsAttacherImpl() + { + } + + // ----------------------------------------------------------------------------- + Reference< script::XScriptListener > + DialogEventsAttacherImpl::getScriptListenerForKey( const rtl::OUString& sKey ) throw ( RuntimeException ) + { + ListenerHash::iterator it = listernersForTypes.find( sKey ); + if ( it == listernersForTypes.end() ) + throw RuntimeException(); // more text info here please + return it->second; + } + Reference< XScriptEventsSupplier > DialogEventsAttacherImpl::getFakeVbaEventsSupplier( const Reference< XControl >& xControl, rtl::OUString& sControlName ) + { + Reference< XScriptEventsSupplier > xEventsSupplier; + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + if ( xSMgr.is() ) + { + Reference< ooo::vba::XVBAToOOEventDescGen > xVBAToOOEvtDesc( xSMgr->createInstanceWithContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAToOOEventDesc" ) ), m_xContext ), UNO_QUERY ); + if ( xVBAToOOEvtDesc.is() ) + xEventsSupplier.set( xVBAToOOEvtDesc->getEventSupplier( xControl, sControlName ), UNO_QUERY ); + } + return xEventsSupplier; + } + + // ----------------------------------------------------------------------------- + void SAL_CALL DialogEventsAttacherImpl::attachEventsToControl( const Reference< XControl>& xControl, const Reference< XScriptEventsSupplier >& xEventsSupplier, const Any& Helper ) + { + if ( xEventsSupplier.is() ) + { + Reference< container::XNameContainer > xEventCont = xEventsSupplier->getEvents(); + + Reference< XControlModel > xControlModel = xControl->getModel(); + if ( xEventCont.is() ) + { + Sequence< ::rtl::OUString > aNames = xEventCont->getElementNames(); + const ::rtl::OUString* pNames = aNames.getConstArray(); + sal_Int32 nNameCount = aNames.getLength(); + + for ( sal_Int32 j = 0; j < nNameCount; ++j ) + { + ScriptEventDescriptor aDesc; + + Any aElement = xEventCont->getByName( pNames[ j ] ); + aElement >>= aDesc; + rtl::OUString sKey = aDesc.ScriptType; + if ( aDesc.ScriptType.equals( rtl::OUString::createFromAscii("Script" ) ) || aDesc.ScriptType.equals( rtl::OUString::createFromAscii("UNO" ) ) ) + { + sal_Int32 nIndex = aDesc.ScriptCode.indexOf( ':' ); + sKey = aDesc.ScriptCode.copy( 0, nIndex ); + } + Reference< XAllListener > xAllListener = + new DialogAllListenerImpl( getScriptListenerForKey( sKey ), aDesc.ScriptType, aDesc.ScriptCode ); + + // try first to attach event to the ControlModel + bool bSuccess = false; + try + { + Reference< XEventListener > xListener_ = m_xEventAttacher->attachSingleEventListener( + xControlModel, xAllListener, Helper, aDesc.ListenerType, + aDesc.AddListenerParam, aDesc.EventMethod ); + + if ( xListener_.is() ) + bSuccess = true; + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + try + { + // if we had no success, try to attach to the control + if ( !bSuccess ) + { + Reference< XEventListener > xListener_ = m_xEventAttacher->attachSingleEventListener( + xControl, xAllListener, Helper, aDesc.ListenerType, + aDesc.AddListenerParam, aDesc.EventMethod ); + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + } + } + + // ----------------------------------------------------------------------------- + // XScriptEventsAttacher + // ----------------------------------------------------------------------------- + + void SAL_CALL DialogEventsAttacherImpl::attachEvents( const Sequence< Reference< XInterface > >& Objects, + const com::sun::star::uno::Reference<com::sun::star::script::XScriptListener>&, + const Any& Helper ) + throw (IllegalArgumentException, IntrospectionException, CannotCreateAdapterException, + ServiceNotRegisteredException, RuntimeException) + { + // get EventAttacher + { + ::osl::MutexGuard aGuard( getMutex() ); + + if ( !m_xEventAttacher.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + if ( xSMgr.is() ) + { + m_xEventAttacher = Reference< XEventAttacher >( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.EventAttacher" ) ), m_xContext ), UNO_QUERY ); + + if ( !m_xEventAttacher.is() ) + throw ServiceNotRegisteredException(); + } + else + { + throw RuntimeException(); + } + + } + } + + // go over all objects + const Reference< XInterface >* pObjects = Objects.getConstArray(); + sal_Int32 nObjCount = Objects.getLength(); + Reference< awt::XControl > xDlgControl( Objects[ nObjCount - 1 ], uno::UNO_QUERY ); // last object is the dialog + rtl::OUString sDialogCodeName; + if ( xDlgControl.is() ) + { + Reference< XPropertySet > xProps( xDlgControl->getModel(), UNO_QUERY ); + try + { + xProps->getPropertyValue( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= sDialogCodeName; + } + catch( Exception& ){} + } + + for ( sal_Int32 i = 0; i < nObjCount; ++i ) + { + // We know that we have to do with instances of XControl. + // Otherwise this is not the right implementation for + // XScriptEventsAttacher and we have to give up. + Reference< XControl > xControl( pObjects[ i ], UNO_QUERY ); + if ( !xControl.is() ) + throw IllegalArgumentException(); + + // get XEventsSupplier from control model + Reference< XControlModel > xControlModel = xControl->getModel(); + Reference< XScriptEventsSupplier > xEventsSupplier( xControlModel, UNO_QUERY ); + attachEventsToControl( xControl, xEventsSupplier, Helper ); + if ( mbUseFakeVBAEvents ) + { + xEventsSupplier.set( getFakeVbaEventsSupplier( xControl, sDialogCodeName ) ); + attachEventsToControl( xControl, xEventsSupplier, Helper ); + } + } + } + + + // ============================================================================= + // DialogAllListenerImpl + // ============================================================================= + + DialogAllListenerImpl::DialogAllListenerImpl( const Reference< XScriptListener >& rxListener, + const ::rtl::OUString& rScriptType, const ::rtl::OUString& rScriptCode ) + :m_xScriptListener( rxListener ) + ,m_sScriptType( rScriptType ) + ,m_sScriptCode( rScriptCode ) + { + } + + // ----------------------------------------------------------------------------- + + DialogAllListenerImpl::~DialogAllListenerImpl() + { + } + + // ----------------------------------------------------------------------------- + + void DialogAllListenerImpl::firing_impl( const AllEventObject& Event, Any* pRet ) + { + ScriptEvent aScriptEvent; + aScriptEvent.Source = (OWeakObject *)this; // get correct XInterface + aScriptEvent.ListenerType = Event.ListenerType; + aScriptEvent.MethodName = Event.MethodName; + aScriptEvent.Arguments = Event.Arguments; + aScriptEvent.Helper = Event.Helper; + aScriptEvent.ScriptType = m_sScriptType; + aScriptEvent.ScriptCode = m_sScriptCode; + + if ( m_xScriptListener.is() ) + { + if ( pRet ) + *pRet = m_xScriptListener->approveFiring( aScriptEvent ); + else + m_xScriptListener->firing( aScriptEvent ); + } + } + + // ----------------------------------------------------------------------------- + // XEventListener + // ----------------------------------------------------------------------------- + + void DialogAllListenerImpl::disposing(const EventObject& ) throw ( RuntimeException ) + { + } + + // ----------------------------------------------------------------------------- + // XAllListener + // ----------------------------------------------------------------------------- + + void DialogAllListenerImpl::firing( const AllEventObject& Event ) throw ( RuntimeException ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + firing_impl( Event, NULL ); + } + + // ----------------------------------------------------------------------------- + + Any DialogAllListenerImpl::approveFiring( const AllEventObject& Event ) + throw ( reflection::InvocationTargetException, RuntimeException ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + Any aReturn; + firing_impl( Event, &aReturn ); + return aReturn; + } + + + // ============================================================================= + // DialogScriptListenerImpl + // ============================================================================= + + DialogUnoScriptListenerImpl::DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext, + const Reference< ::com::sun::star::frame::XModel >& rxModel, + const Reference< ::com::sun::star::awt::XControl >& rxControl, + const Reference< ::com::sun::star::uno::XInterface >& rxHandler, + const Reference< ::com::sun::star::beans::XIntrospectionAccess >& rxIntrospectionAccess, + bool bDialogProviderMode ) + : DialogSFScriptListenerImpl( rxContext, rxModel ) + ,m_xControl( rxControl ) + ,m_xHandler( rxHandler ) + ,m_xIntrospectionAccess( rxIntrospectionAccess ) + ,m_bDialogProviderMode( bDialogProviderMode ) + { + } + + // ----------------------------------------------------------------------------- + + DialogScriptListenerImpl::~DialogScriptListenerImpl() + { + } + + // ----------------------------------------------------------------------------- + void DialogSFScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet ) + { + try + { + Reference< provider::XScriptProvider > xScriptProvider; + if ( m_xModel.is() ) + { + Reference< provider::XScriptProviderSupplier > xSupplier( m_xModel, UNO_QUERY ); + OSL_ENSURE( xSupplier.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider supplier" ); + if ( xSupplier.is() ) + xScriptProvider.set( xSupplier->getScriptProvider() ); + } + else + { + OSL_ASSERT( m_xContext.is() ); + if ( m_xContext.is() ) + { + Reference< provider::XScriptProviderFactory > xFactory( + m_xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory" ) ), + UNO_QUERY ); + OSL_ENSURE( xFactory.is(), "SFURL_firing_impl: failed to get master script provider factory" ); + if ( xFactory.is() ) + { + Any aCtx; + aCtx <<= ::rtl::OUString::createFromAscii( "user" ); + xScriptProvider.set( xFactory->createScriptProvider( aCtx ), UNO_QUERY ); + } + } + } + + OSL_ENSURE( xScriptProvider.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider" ); + + if ( xScriptProvider.is() ) + { + Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode ); + OSL_ENSURE( xScript.is(), "DialogScriptListenerImpl::firing_impl: failed to get script" ); + + if ( xScript.is() ) + { + Sequence< Any > aInParams; + Sequence< sal_Int16 > aOutParamsIndex; + Sequence< Any > aOutParams; + + // get arguments for script + aInParams = aScriptEvent.Arguments; + + Any aResult = xScript->invoke( aInParams, aOutParamsIndex, aOutParams ); + if ( pRet ) + *pRet = aResult; + } + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + void DialogLegacyScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet ) + { + ::rtl::OUString sScriptURL; + ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode ); + + if ( aScriptEvent.ScriptType.compareToAscii( "StarBasic" ) == 0 ) + { + // StarBasic script: convert ScriptCode to scriptURL + sal_Int32 nIndex = sScriptCode.indexOf( ':' ); + if ( nIndex >= 0 && nIndex < sScriptCode.getLength() ) + { + sScriptURL = ::rtl::OUString::createFromAscii( "vnd.sun.star.script:" ); + sScriptURL += sScriptCode.copy( nIndex + 1 ); + sScriptURL += ::rtl::OUString::createFromAscii( "?language=Basic&location=" ); + sScriptURL += sScriptCode.copy( 0, nIndex ); + } + ScriptEvent aSFScriptEvent( aScriptEvent ); + aSFScriptEvent.ScriptCode = sScriptURL; + DialogSFScriptListenerImpl::firing_impl( aSFScriptEvent, pRet ); + } + } + + void DialogUnoScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet ) + { + static ::rtl::OUString sUnoURLScheme = ::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" ); + + ::rtl::OUString sScriptCode( aScriptEvent.ScriptCode ); + ::rtl::OUString aMethodName = aScriptEvent.ScriptCode.copy( sUnoURLScheme.getLength() ); + + const Any* pArguments = aScriptEvent.Arguments.getConstArray(); + Any aEventObject = pArguments[0]; + + bool bHandled = false; + if( m_xHandler.is() ) + { + if( m_bDialogProviderMode ) + { + Reference< XDialogEventHandler > xDialogEventHandler( m_xHandler, UNO_QUERY ); + if( xDialogEventHandler.is() ) + { + Reference< XDialog > xDialog( m_xControl, UNO_QUERY ); + bHandled = xDialogEventHandler->callHandlerMethod( xDialog, aEventObject, aMethodName ); + } + } + else + { + Reference< XContainerWindowEventHandler > xContainerWindowEventHandler( m_xHandler, UNO_QUERY ); + if( xContainerWindowEventHandler.is() ) + { + Reference< XWindow > xWindow( m_xControl, UNO_QUERY ); + bHandled = xContainerWindowEventHandler->callHandlerMethod( xWindow, aEventObject, aMethodName ); + } + } + } + + Any aRet; + if( !bHandled && m_xIntrospectionAccess.is() ) + { + try + { + // Methode ansprechen + const Reference< XIdlMethod >& rxMethod = m_xIntrospectionAccess-> + getMethod( aMethodName, MethodConcept::ALL - MethodConcept::DANGEROUS ); + + Reference< XMaterialHolder > xMaterialHolder = + Reference< XMaterialHolder >::query( m_xIntrospectionAccess ); + Any aHandlerObject = xMaterialHolder->getMaterial(); + + Sequence< Reference< XIdlClass > > aParamTypeSeq = rxMethod->getParameterTypes(); + sal_Int32 nParamCount = aParamTypeSeq.getLength(); + if( nParamCount == 0 ) + { + Sequence<Any> args; + rxMethod->invoke( aHandlerObject, args ); + bHandled = true; + } + else if( nParamCount == 2 ) + { + // Signature check automatically done by reflection + Sequence<Any> Args(2); + Any* pArgs = Args.getArray(); + if( m_bDialogProviderMode ) + { + Reference< XDialog > xDialog( m_xControl, UNO_QUERY ); + pArgs[0] <<= xDialog; + } + else + { + Reference< XWindow > xWindow( m_xControl, UNO_QUERY ); + pArgs[0] <<= xWindow; + } + pArgs[1] = aEventObject; + aRet = rxMethod->invoke( aHandlerObject, Args ); + bHandled = true; + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + if( bHandled ) + { + if( pRet ) + *pRet = aRet; + } + else + { + ResMgr* pResMgr = SFX_APP()->GetSfxResManager(); + if( pResMgr ) + { + String aRes( ResId(STR_ERRUNOEVENTBINDUNG, *pResMgr) ); + ::rtl::OUString aQuoteChar( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ); + + ::rtl::OUString aOURes = aRes; + sal_Int32 nIndex = aOURes.indexOf( '%' ); + + ::rtl::OUString aOUFinal; + aOUFinal += aOURes.copy( 0, nIndex ); + aOUFinal += aQuoteChar; + aOUFinal += aMethodName; + aOUFinal += aQuoteChar; + aOUFinal += aOURes.copy( nIndex + 2 ); + + ErrorBox( NULL, WinBits( WB_OK ), aOUFinal ).Execute(); + } + } + } + + // ----------------------------------------------------------------------------- + // XEventListener + // ----------------------------------------------------------------------------- + + void DialogScriptListenerImpl::disposing(const EventObject& ) throw ( RuntimeException ) + { + } + + // ----------------------------------------------------------------------------- + // XScriptListener + // ----------------------------------------------------------------------------- + + void DialogScriptListenerImpl::firing( const ScriptEvent& aScriptEvent ) throw ( RuntimeException ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + firing_impl( aScriptEvent, NULL ); + } + + // ----------------------------------------------------------------------------- + + Any DialogScriptListenerImpl::approveFiring( const ScriptEvent& aScriptEvent ) + throw ( reflection::InvocationTargetException, RuntimeException ) + { + ::osl::MutexGuard aGuard( getMutex() ); + + Any aReturn; + firing_impl( aScriptEvent, &aReturn ); + return aReturn; + } + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace dlgprov +//......................................................................... diff --git a/scripting/source/dlgprov/dlgevtatt.hxx b/scripting/source/dlgprov/dlgevtatt.hxx new file mode 100644 index 000000000000..85b0bfcd087d --- /dev/null +++ b/scripting/source/dlgprov/dlgevtatt.hxx @@ -0,0 +1,164 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_DLGEVTATT_HXX +#define SCRIPTING_DLGEVTATT_HXX + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/script/XAllListener.hpp> +#include <com/sun/star/script/XEventAttacher.hpp> +#include <com/sun/star/script/XScriptEventsAttacher.hpp> +#include <com/sun/star/script/XScriptListener.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/awt/XControl.hpp> +#ifndef _COM_SUN_STAR_BEANS_XINTROSPECTION_HPP_ +#include <com/sun/star/beans/XIntrospectionAccess.hpp> +#endif +#include <cppuhelper/implbase1.hxx> + +#include <com/sun/star/script/XScriptEventsSupplier.hpp> + +#include <hash_map> + +//......................................................................... +namespace dlgprov +{ +//......................................................................... + + // ============================================================================= + // class DialogEventsAttacherImpl + // ============================================================================= + typedef std::hash_map< rtl::OUString, + ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener >, + ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > ListenerHash; + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::XScriptEventsAttacher > DialogEventsAttacherImpl_BASE; + + + class DialogEventsAttacherImpl : public DialogEventsAttacherImpl_BASE + { + private: + bool mbUseFakeVBAEvents; + ListenerHash listernersForTypes; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XEventAttacher > m_xEventAttacher; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener > getScriptListenerForKey( const rtl::OUString& sScriptName ) throw ( ::com::sun::star::uno::RuntimeException ); + ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptEventsSupplier > getFakeVbaEventsSupplier( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& xControl, rtl::OUString& sCodeName ); + void SAL_CALL attachEventsToControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl>& xControl, const ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptEventsSupplier >& events, const ::com::sun::star::uno::Any& Helper ); + public: + DialogEventsAttacherImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& xControl, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xHandler, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >& xIntrospect, + bool bProviderMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener >& xRTLListener ); + virtual ~DialogEventsAttacherImpl(); + + // XScriptEventsAttacher + virtual void SAL_CALL attachEvents( const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >& Objects, + const com::sun::star::uno::Reference<com::sun::star::script::XScriptListener>&, + const ::com::sun::star::uno::Any& Helper ) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::beans::IntrospectionException, + ::com::sun::star::script::CannotCreateAdapterException, + ::com::sun::star::lang::ServiceNotRegisteredException, + ::com::sun::star::uno::RuntimeException); + }; + + + // ============================================================================= + // class DialogAllListenerImpl + // ============================================================================= + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::XAllListener > DialogAllListenerImpl_BASE; + + + class DialogAllListenerImpl : public DialogAllListenerImpl_BASE + { + private: + ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener > m_xScriptListener; + ::rtl::OUString m_sScriptType; + ::rtl::OUString m_sScriptCode; + + virtual void firing_impl( const ::com::sun::star::script::AllEventObject& Event, ::com::sun::star::uno::Any* pRet ); + + public: + DialogAllListenerImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener >& rxListener, + const ::rtl::OUString& rScriptType, const ::rtl::OUString& rScriptCode ); + virtual ~DialogAllListenerImpl(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException); + + // XAllListener + virtual void SAL_CALL firing( const ::com::sun::star::script::AllEventObject& Event ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL approveFiring( const ::com::sun::star::script::AllEventObject& Event ) + throw (::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + }; + + + // ============================================================================= + // class DialogScriptListenerImpl + // ============================================================================= + + typedef ::cppu::WeakImplHelper1< + ::com::sun::star::script::XScriptListener > DialogScriptListenerImpl_BASE; + + + class DialogScriptListenerImpl : public DialogScriptListenerImpl_BASE + { + protected: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + virtual void firing_impl( const ::com::sun::star::script::ScriptEvent& aScriptEvent, ::com::sun::star::uno::Any* pRet ) = 0; + public: + DialogScriptListenerImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ) : m_xContext( rxContext ) {} + virtual ~DialogScriptListenerImpl(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException); + + // XScriptListener + virtual void SAL_CALL firing( const ::com::sun::star::script::ScriptEvent& aScriptEvent ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL approveFiring( const ::com::sun::star::script::ScriptEvent& aScriptEvent ) + throw (::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException); + }; + + +//......................................................................... +} // namespace dlgprov +//......................................................................... + +#endif // SCRIPTING_DLGEVT_HXX diff --git a/scripting/source/dlgprov/dlgprov.cxx b/scripting/source/dlgprov/dlgprov.cxx new file mode 100644 index 000000000000..0fc0778c71d9 --- /dev/null +++ b/scripting/source/dlgprov/dlgprov.cxx @@ -0,0 +1,870 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include "dlgprov.hxx" +#include "dlgevtatt.hxx" +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/io/XInputStreamProvider.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/resource/XStringResourceSupplier.hpp> +#include <com/sun/star/resource/XStringResourceManager.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/resource/XStringResourceWithLocation.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> +#include <sfx2/app.hxx> +#include <sfx2/objsh.hxx> +#include <xmlscript/xmldlg_imexp.hxx> +#include <tools/urlobj.hxx> +#include <comphelper/namedvaluecollection.hxx> + +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> +#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> + +#include <util/MiscUtils.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::document; +using namespace ::sf_misc; + +//......................................................................... +namespace dlgprov +{ +//......................................................................... + +static ::rtl::OUString aResourceResolverPropName = ::rtl::OUString::createFromAscii( "ResourceResolver" ); + // ============================================================================= + // component operations + // ============================================================================= + + static ::rtl::OUString getImplementationName_DialogProviderImpl() + { + static ::rtl::OUString* pImplName = 0; + if ( !pImplName ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pImplName ) + { + static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.DialogProvider" ) ); + pImplName = &aImplName; + } + } + return *pImplName; + } + + // ----------------------------------------------------------------------------- + + static Sequence< ::rtl::OUString > getSupportedServiceNames_DialogProviderImpl() + { + static Sequence< ::rtl::OUString >* pNames = 0; + if ( !pNames ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pNames ) + { + static Sequence< ::rtl::OUString > aNames(3); + aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider" ) ); + aNames.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ); + aNames.getArray()[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.ContainerWindowProvider" ) ); + pNames = &aNames; + } + } + return *pNames; + } + + + // ============================================================================= + // mutex + // ============================================================================= + + ::osl::Mutex& getMutex() + { + static ::osl::Mutex* s_pMutex = 0; + if ( !s_pMutex ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !s_pMutex ) + { + static ::osl::Mutex s_aMutex; + s_pMutex = &s_aMutex; + } + } + return *s_pMutex; + } + + + // ============================================================================= + // DialogProviderImpl + // ============================================================================= + + DialogProviderImpl::DialogProviderImpl( const Reference< XComponentContext >& rxContext ) + :m_xContext( rxContext ) + ,m_xModel( 0 ) + { + } + + // ----------------------------------------------------------------------------- + + DialogProviderImpl::~DialogProviderImpl() + { + } + + // ----------------------------------------------------------------------------- + + Reference< resource::XStringResourceManager > getStringResourceFromDialogLibrary + ( Reference< container::XNameContainer > xDialogLib ) + { + Reference< resource::XStringResourceManager > xStringResourceManager; + if( xDialogLib.is() ) + { + Reference< resource::XStringResourceSupplier > xStringResourceSupplier( xDialogLib, UNO_QUERY ); + if( xStringResourceSupplier.is() ) + { + Reference< resource::XStringResourceResolver > + xStringResourceResolver = xStringResourceSupplier->getStringResource(); + + xStringResourceManager = + Reference< resource::XStringResourceManager >( xStringResourceResolver, UNO_QUERY ); + } + } + return xStringResourceManager; + } + + Reference< container::XNameContainer > DialogProviderImpl::createControlModel() throw ( Exception ) + { + Reference< XMultiComponentFactory > xSMgr_( m_xContext->getServiceManager(), UNO_QUERY_THROW ); + Reference< container::XNameContainer > xControlModel( xSMgr_->createInstanceWithContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ), m_xContext ), UNO_QUERY_THROW ); + return xControlModel; + } + + Reference< container::XNameContainer > DialogProviderImpl::createDialogModel( + const Reference< io::XInputStream >& xInput, + const Reference< resource::XStringResourceManager >& xStringResourceManager, + const Any &aDialogSourceURL) throw ( Exception ) + { + Reference< container::XNameContainer > xDialogModel( createControlModel() ); + + ::rtl::OUString aDlgSrcUrlPropName( RTL_CONSTASCII_USTRINGPARAM( "DialogSourceURL" ) ); + Reference< beans::XPropertySet > xDlgPropSet( xDialogModel, UNO_QUERY ); + xDlgPropSet->setPropertyValue( aDlgSrcUrlPropName, aDialogSourceURL ); + + ::xmlscript::importDialogModel( xInput, xDialogModel, m_xContext ); + // Set resource property + if( xStringResourceManager.is() ) + { + Reference< beans::XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY ); + Any aStringResourceManagerAny; + aStringResourceManagerAny <<= xStringResourceManager; + xDlgPSet->setPropertyValue( aResourceResolverPropName, aStringResourceManagerAny ); + } + + return xDialogModel; + } + + Reference< XControlModel > DialogProviderImpl::createDialogModelForBasic() throw ( Exception ) + { + if ( !m_BasicInfo.get() ) + // shouln't get here + throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("No information to create dialog" ) ), Reference< XInterface >() ); + Reference< resource::XStringResourceManager > xStringResourceManager = getStringResourceFromDialogLibrary( m_BasicInfo->mxDlgLib ); + + rtl::OUString aURL(RTL_CONSTASCII_USTRINGPARAM("" )); + Any aDialogSourceURL; + aDialogSourceURL <<= aURL; + Reference< XControlModel > xCtrlModel( createDialogModel( m_BasicInfo->mxInput, xStringResourceManager, aDialogSourceURL ), UNO_QUERY_THROW ); + return xCtrlModel; + } + + Reference< XControlModel > DialogProviderImpl::createDialogModel( const ::rtl::OUString& sURL ) + { + + ::rtl::OUString aURL( sURL ); + + // parse URL + // TODO: use URL parsing class + // TODO: decoding of location + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + + if ( !xSMgr.is() ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: Couldn't instantiate MultiComponent factory" ) ), + Reference< XInterface >() ); + } + + Reference< uri::XUriReferenceFactory > xFac ( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); + + if ( !xFac.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "DialogProviderImpl::getDialogModel(), could not instatiate UriReferenceFactory." ), + Reference< XInterface >() ); + } + + // i75778: Support non-script URLs + Reference< io::XInputStream > xInput; + Reference< container::XNameContainer > xDialogLib; + + // Accept file URL to single dialog + bool bSingleDialog = false; + + Reference< util::XMacroExpander > xMacroExpander( + m_xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), + UNO_QUERY_THROW ); + + Reference< uri::XUriReference > uriRef; + for (;;) + { + uriRef = Reference< uri::XUriReference >( xFac->parse( aURL ), UNO_QUERY ); + if ( !uriRef.is() ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "DialogProviderImpl::getDialogModel: failed to parse URI: " ); + errorMsg += aURL; + throw IllegalArgumentException( errorMsg, + Reference< XInterface >(), 1 ); + } + Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); + if( !sxUri.is() ) + break; + + aURL = sxUri->expand( xMacroExpander ); + } + + Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY ); + if( !sfUri.is() ) + { + bSingleDialog = true; + + // Try any other URL with SimpleFileAccess + Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSFI = + Reference< ::com::sun::star::ucb::XSimpleFileAccess >( xSMgr->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ), UNO_QUERY ); + + try + { + xInput = xSFI->openFileRead( aURL ); + } + catch( Exception& ) + {} + } + else + { + ::rtl::OUString sDescription = sfUri->getName(); + + sal_Int32 nIndex = 0; + + ::rtl::OUString sLibName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex ); + ::rtl::OUString sDlgName; + if ( nIndex != -1 ) + sDlgName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex ); + + ::rtl::OUString sLocation = sfUri->getParameter( + ::rtl::OUString::createFromAscii( "location" ) ); + + + // get dialog library container + // TODO: dialogs in packages + Reference< XLibraryContainer > xLibContainer; + + if ( sLocation == ::rtl::OUString::createFromAscii( "application" ) ) + { + xLibContainer = Reference< XLibraryContainer >( SFX_APP()->GetDialogContainer(), UNO_QUERY ); + } + else if ( sLocation == ::rtl::OUString::createFromAscii( "document" ) ) + { + Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY ); + if ( xDocumentScripts.is() ) + { + xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY ); + OSL_ENSURE( xLibContainer.is(), + "DialogProviderImpl::createDialogModel: invalid dialog container!" ); + } + } + else + { + Sequence< ::rtl::OUString > aOpenDocsTdocURLs( MiscUtils::allOpenTDocUrls( m_xContext ) ); + const ::rtl::OUString* pTdocURL = aOpenDocsTdocURLs.getConstArray(); + const ::rtl::OUString* pTdocURLEnd = aOpenDocsTdocURLs.getConstArray() + aOpenDocsTdocURLs.getLength(); + for ( ; pTdocURL != pTdocURLEnd; ++pTdocURL ) + { + Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( *pTdocURL ) ); + OSL_ENSURE( xModel.is(), "DialogProviderImpl::createDialogModel: invalid document model!" ); + if ( !xModel.is() ) + continue; + + ::rtl::OUString sDocURL = xModel->getURL(); + if ( sDocURL.getLength() == 0 ) + { + ::comphelper::NamedValueCollection aModelArgs( xModel->getArgs() ); + sDocURL = aModelArgs.getOrDefault( "Title", sDocURL ); + } + + if ( sLocation != sDocURL ) + continue; + + Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY ); + if ( !xDocumentScripts.is() ) + continue; + + xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY ); + OSL_ENSURE( xLibContainer.is(), + "DialogProviderImpl::createDialogModel: invalid dialog container!" ); + } + } + + // get input stream provider + Reference< io::XInputStreamProvider > xISP; + if ( xLibContainer.is() ) + { + // load dialog library + if ( !xLibContainer->isLibraryLoaded( sLibName ) ) + xLibContainer->loadLibrary( sLibName ); + + // get dialog library + if ( xLibContainer->hasByName( sLibName ) ) + { + Any aElement = xLibContainer->getByName( sLibName ); + aElement >>= xDialogLib; + } + + if ( xDialogLib.is() ) + { + // get input stream provider + if ( xDialogLib->hasByName( sDlgName ) ) + { + Any aElement = xDialogLib->getByName( sDlgName ); + aElement >>= xISP; + } + + if ( !xISP.is() ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: dialog not found!" ) ), + Reference< XInterface >(), 1 ); + } + } + else + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: library not found!" ) ), + Reference< XInterface >(), 1 ); + } + } + else + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialog: library container not found!" ) ), + Reference< XInterface >(), 1 ); + } + + if ( xISP.is() ) + xInput = xISP->createInputStream(); + } + + // import dialog model + Reference< XControlModel > xCtrlModel; + if ( xInput.is() && m_xContext.is() ) + { + Reference< resource::XStringResourceManager > xStringResourceManager; + if( bSingleDialog ) + { + INetURLObject aInetObj( aURL ); + ::rtl::OUString aDlgName = aInetObj.GetBase(); + aInetObj.removeSegment(); + ::rtl::OUString aDlgLocation = aInetObj.GetMainURL( INetURLObject::NO_DECODE ); + bool bReadOnly = true; + ::com::sun ::star::lang::Locale aLocale = Application::GetSettings().GetUILocale(); + ::rtl::OUString aComment; + + Sequence<Any> aArgs( 6 ); + aArgs[0] <<= aDlgLocation; + aArgs[1] <<= bReadOnly; + aArgs[2] <<= aLocale; + aArgs[3] <<= aDlgName; + aArgs[4] <<= aComment; + + Reference< task::XInteractionHandler > xDummyHandler; + aArgs[5] <<= xDummyHandler; + Reference< XMultiComponentFactory > xSMgr_( m_xContext->getServiceManager(), UNO_QUERY_THROW ); + // TODO: Ctor + xStringResourceManager = Reference< resource::XStringResourceManager >( xSMgr_->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.resource.StringResourceWithLocation" ), + m_xContext ), UNO_QUERY ); + if( xStringResourceManager.is() ) + { + Reference< XInitialization > xInit( xStringResourceManager, UNO_QUERY ); + if( xInit.is() ) + xInit->initialize( aArgs ); + } + } + else if( xDialogLib.is() ) + { + xStringResourceManager = getStringResourceFromDialogLibrary( xDialogLib ); + } + + Any aDialogSourceURLAny; + aDialogSourceURLAny <<= aURL; + + Reference< container::XNameContainer > xDialogModel( createDialogModel( xInput , xStringResourceManager, aDialogSourceURLAny ), UNO_QUERY_THROW); + + xCtrlModel = Reference< XControlModel >( xDialogModel, UNO_QUERY ); + } + return xCtrlModel; + } + + // ----------------------------------------------------------------------------- + + Reference< XControl > DialogProviderImpl::createDialogControl + ( const Reference< XControlModel >& rxDialogModel, const Reference< XWindowPeer >& xParent ) + { + OSL_ENSURE( rxDialogModel.is(), "DialogProviderImpl::getDialogControl: no dialog model" ); + + Reference< XControl > xDialogControl; + + if ( m_xContext.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); + + if ( xSMgr.is() ) + { + xDialogControl = Reference< XControl >( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialog" ) ), m_xContext ), UNO_QUERY ); + + if ( xDialogControl.is() ) + { + // set the model + if ( rxDialogModel.is() ) + xDialogControl->setModel( rxDialogModel ); + + // set visible + Reference< XWindow > xW( xDialogControl, UNO_QUERY ); + if ( xW.is() ) + xW->setVisible( sal_False ); + + // get the parent of the dialog control + Reference< XWindowPeer > xPeer; + if( xParent.is() ) + { + xPeer = xParent; + } + else if ( m_xModel.is() ) + { + Reference< frame::XController > xController( m_xModel->getCurrentController(), UNO_QUERY ); + if ( xController.is() ) + { + Reference< frame::XFrame > xFrame( xController->getFrame(), UNO_QUERY ); + if ( xFrame.is() ) + xPeer = Reference< XWindowPeer>( xFrame->getContainerWindow(), UNO_QUERY ); + } + } + + // create a peer + Reference< XToolkit> xToolkit( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ), m_xContext ), UNO_QUERY ); + if ( xToolkit.is() ) + xDialogControl->createPeer( xToolkit, xPeer ); + } + } + } + + return xDialogControl; + } + + // ----------------------------------------------------------------------------- + + void DialogProviderImpl::attachControlEvents( + const Reference< XControl >& rxControl, + const Reference< XInterface >& rxHandler, + const Reference< XIntrospectionAccess >& rxIntrospectionAccess, + bool bDialogProviderMode ) + { + if ( rxControl.is() ) + { + Reference< XControlContainer > xControlContainer( rxControl, UNO_QUERY ); + + if ( xControlContainer.is() ) + { + Sequence< Reference< XControl > > aControls = xControlContainer->getControls(); + const Reference< XControl >* pControls = aControls.getConstArray(); + sal_Int32 nControlCount = aControls.getLength(); + + Sequence< Reference< XInterface > > aObjects( nControlCount + 1 ); + Reference< XInterface >* pObjects = aObjects.getArray(); + for ( sal_Int32 i = 0; i < nControlCount; ++i ) + { + pObjects[i] = Reference< XInterface >( pControls[i], UNO_QUERY ); + } + + // also add the dialog control itself to the sequence + pObjects[nControlCount] = Reference< XInterface >( rxControl, UNO_QUERY ); + + Reference< XScriptEventsAttacher > xScriptEventsAttacher = new DialogEventsAttacherImpl + ( m_xContext, m_xModel, rxControl, rxHandler, rxIntrospectionAccess, + bDialogProviderMode, ( m_BasicInfo.get() ? m_BasicInfo->mxBasicRTLListener : NULL ) ); + + Any aHelper; + xScriptEventsAttacher->attachEvents( aObjects, Reference< XScriptListener >(), aHelper ); + } + } + } + + Reference< XIntrospectionAccess > DialogProviderImpl::inspectHandler( const Reference< XInterface >& rxHandler ) + { + Reference< XIntrospectionAccess > xIntrospectionAccess; + static Reference< XIntrospection > xIntrospection; + + if( !rxHandler.is() ) + return xIntrospectionAccess; + + if( !xIntrospection.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + if ( !xSMgr.is() ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getIntrospectionAccess: Couldn't instantiate MultiComponent factory" ) ), + Reference< XInterface >() ); + } + + // Get introspection service + Reference< XInterface > xI = xSMgr->createInstanceWithContext + ( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection"), m_xContext ); + if (xI.is()) + xIntrospection = Reference< XIntrospection >::query( xI ); + } + + if( xIntrospection.is() ) + { + // Do introspection + try + { + Any aHandlerAny; + aHandlerAny <<= rxHandler; + xIntrospectionAccess = xIntrospection->inspect( aHandlerAny ); + } + catch( RuntimeException& ) + { + xIntrospectionAccess.clear(); + } + } + return xIntrospectionAccess; + } + + + // ----------------------------------------------------------------------------- + // XServiceInfo + // ----------------------------------------------------------------------------- + + ::rtl::OUString DialogProviderImpl::getImplementationName( ) throw (RuntimeException) + { + return getImplementationName_DialogProviderImpl(); + } + + // ----------------------------------------------------------------------------- + + sal_Bool DialogProviderImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; + } + + // ----------------------------------------------------------------------------- + + Sequence< ::rtl::OUString > DialogProviderImpl::getSupportedServiceNames( ) throw (RuntimeException) + { + return getSupportedServiceNames_DialogProviderImpl(); + } + + // ----------------------------------------------------------------------------- + // XInitialization + // ----------------------------------------------------------------------------- + + void DialogProviderImpl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) + { + ::osl::MutexGuard aGuard( getMutex() ); + + if ( aArguments.getLength() == 1 ) + { + aArguments[0] >>= m_xModel; + + if ( !m_xModel.is() ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::initialize: invalid argument format!" ) ), + Reference< XInterface >() ); + } + } + else if ( aArguments.getLength() == 4 ) + { + // call from RTL_Impl_CreateUnoDialog + aArguments[0] >>= m_xModel; + m_BasicInfo.reset( new BasicRTLParams() ); + m_BasicInfo->mxInput.set( aArguments[ 1 ], UNO_QUERY_THROW ); + m_BasicInfo->mxDlgLib.set( aArguments[ 2 ], UNO_QUERY_THROW ); + // leave the possibility to optionally allow the old dialog creation + // to use the new XScriptListener ( which converts the old style macro + // to a SF url ) + m_BasicInfo->mxBasicRTLListener.set( aArguments[ 3 ], UNO_QUERY); + } + else if ( aArguments.getLength() > 4 ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::initialize: invalid number of arguments!" ) ), + Reference< XInterface >() ); + } + } + + // ----------------------------------------------------------------------------- + // XDialogProvider + // ----------------------------------------------------------------------------- + + static ::rtl::OUString aDecorationPropName = + ::rtl::OUString::createFromAscii( "Decoration" ); + static ::rtl::OUString aTitlePropName = + ::rtl::OUString::createFromAscii( "Title" ); + + Reference < XControl > DialogProviderImpl::createDialogImpl( + const ::rtl::OUString& URL, const Reference< XInterface >& xHandler, + const Reference< XWindowPeer >& xParent, bool bDialogProviderMode ) + throw (IllegalArgumentException, RuntimeException) + { + // if the dialog is located in a document, the document must already be open! + + ::osl::MutexGuard aGuard( getMutex() ); + + + // m_xHandler = xHandler; + + //Reference< XDialog > xDialog; + Reference< XControl > xCtrl; + Reference< XControlModel > xCtrlMod; + try + { + // add support for basic RTL_FUNCTION + if ( m_BasicInfo.get() ) + xCtrlMod = createDialogModelForBasic(); + else + { + OSL_ENSURE( URL.getLength(), "DialogProviderImpl::getDialog: no URL!" ); + xCtrlMod = createDialogModel( URL ); + } + } + catch ( const RuntimeException& ) { throw; } + catch ( const Exception& ) + { + const Any aError( ::cppu::getCaughtException() ); + throw WrappedTargetRuntimeException( ::rtl::OUString(), *this, aError ); + } + if ( xCtrlMod.is() ) + { + // i83963 Force decoration + if( bDialogProviderMode ) + { + uno::Reference< beans::XPropertySet > xDlgModPropSet( xCtrlMod, uno::UNO_QUERY ); + if( xDlgModPropSet.is() ) + { + bool bDecoration = true; + try + { + Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName ); + aDecorationAny >>= bDecoration; + if( !bDecoration ) + { + xDlgModPropSet->setPropertyValue( aDecorationPropName, makeAny( true ) ); + xDlgModPropSet->setPropertyValue( aTitlePropName, makeAny( ::rtl::OUString() ) ); + } + } + catch( UnknownPropertyException& ) + {} + } + } + + xCtrl = Reference< XControl >( createDialogControl( xCtrlMod, xParent ) ); + if ( xCtrl.is() ) + { + //xDialog = Reference< XDialog >( xCtrl, UNO_QUERY ); + Reference< XIntrospectionAccess > xIntrospectionAccess = inspectHandler( xHandler ); + attachControlEvents( xCtrl, xHandler, xIntrospectionAccess, bDialogProviderMode ); + } + } + + return xCtrl; + } + + Reference < XDialog > DialogProviderImpl::createDialog( const ::rtl::OUString& URL ) + throw (IllegalArgumentException, RuntimeException) + { + Reference< XInterface > xDummyHandler; + Reference< XWindowPeer > xDummyPeer; + Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xDummyHandler, xDummyPeer, true ); + Reference< XDialog > xDialog( xControl, UNO_QUERY ); + return xDialog; + } + + Reference < XDialog > DialogProviderImpl::createDialogWithHandler( + const ::rtl::OUString& URL, const Reference< XInterface >& xHandler ) + throw (IllegalArgumentException, RuntimeException) + { + if( !xHandler.is() ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::createDialogWithHandler: Invalid xHandler!" ) ), + Reference< XInterface >(), 1 ); + } + Reference< XWindowPeer > xDummyPeer; + Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xDummyPeer, true ); + Reference< XDialog > xDialog( xControl, UNO_QUERY ); + return xDialog; + } + + Reference < XDialog > DialogProviderImpl::createDialogWithArguments( + const ::rtl::OUString& URL, const Sequence< NamedValue >& Arguments ) + throw (IllegalArgumentException, RuntimeException) + { + ::comphelper::NamedValueCollection aArguments( Arguments ); + + Reference< XWindowPeer > xParentPeer; + if ( aArguments.has( "ParentWindow" ) ) + { + const Any aParentWindow( aArguments.get( "ParentWindow" ) ); + if ( !( aParentWindow >>= xParentPeer ) ) + { + const Reference< XControl > xParentControl( aParentWindow, UNO_QUERY ); + if ( xParentControl.is() ) + xParentPeer = xParentControl->getPeer(); + } + } + + const Reference< XInterface > xHandler( aArguments.get( "EventHandler" ), UNO_QUERY ); + + Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParentPeer, true ); + Reference< XDialog > xDialog( xControl, UNO_QUERY ); + return xDialog; + } + + Reference< XWindow > DialogProviderImpl::createContainerWindow( + const ::rtl::OUString& URL, const ::rtl::OUString& WindowType, + const Reference< XWindowPeer >& xParent, const Reference< XInterface >& xHandler ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) + { + (void)WindowType; // for future use + if( !xParent.is() ) + { + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::createContainerWindow: Invalid xParent!" ) ), + Reference< XInterface >(), 1 ); + } + Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParent, false ); + Reference< XWindow> xWindow( xControl, UNO_QUERY ); + return xWindow; + } + + + // ============================================================================= + // component operations + // ============================================================================= + + static Reference< XInterface > SAL_CALL create_DialogProviderImpl( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) + { + return static_cast< lang::XTypeProvider * >( new DialogProviderImpl( xContext ) ); + } + + // ----------------------------------------------------------------------------- + + static struct ::cppu::ImplementationEntry s_component_entries [] = + { + { + create_DialogProviderImpl, getImplementationName_DialogProviderImpl, + getSupportedServiceNames_DialogProviderImpl, ::cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; + + // ----------------------------------------------------------------------------- + +//......................................................................... +} // namespace dlgprov +//......................................................................... + + +// ============================================================================= +// component exports +// ============================================================================= + +extern "C" +{ + void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) + { + (void)ppEnv; + + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_writeInfoHelper( + pServiceManager, pRegistryKey, ::dlgprov::s_component_entries ); + } + + void * SAL_CALL component_getFactory( + const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, ::dlgprov::s_component_entries ); + } +} diff --git a/scripting/source/dlgprov/dlgprov.hxx b/scripting/source/dlgprov/dlgprov.hxx new file mode 100644 index 000000000000..bc15831d2ff1 --- /dev/null +++ b/scripting/source/dlgprov/dlgprov.hxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_DLGPROV_HXX +#define SCRIPTING_DLGPROV_HXX + +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/awt/XDialogProvider2.hpp> +#include <com/sun/star/awt/XContainerWindowProvider.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/script/XScriptEventsAttacher.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XIntrospectionAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/resource/XStringResourceManager.hpp> + +#include <cppuhelper/implbase4.hxx> +#include <osl/mutex.hxx> +#include <memory> + +//......................................................................... +namespace dlgprov +{ +//......................................................................... + + // ============================================================================= + // mutex + // ============================================================================= + + ::osl::Mutex& getMutex(); + + + // ============================================================================= + // class DialogProviderImpl + // ============================================================================= + + typedef ::cppu::WeakImplHelper4< + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::awt::XDialogProvider2, + ::com::sun::star::awt::XContainerWindowProvider > DialogProviderImpl_BASE; + + class DialogProviderImpl : public DialogProviderImpl_BASE + { + private: + struct BasicRTLParams + { + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > mxInput; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > mxDlgLib; + ::com::sun::star::uno::Reference< ::com::sun::star::script::XScriptListener > mxBasicRTLListener; + }; + std::auto_ptr< BasicRTLParams > m_BasicInfo; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xModel; + + + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > createDialogModel( const ::rtl::OUString& sURL ); + + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > createDialogControl( + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxDialogModel, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParent ); + + void attachControlEvents( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& rxControlContainer, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxHandler, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >& rxIntrospectionAccess, + bool bDialogProviderMode ); + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess > inspectHandler( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxHandler ); + // helper methods + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > createControlModel() throw ( ::com::sun::star::uno::Exception ); + ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > createDialogModel( + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInput, + const ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourceManager >& xStringResourceManager, + const ::com::sun::star::uno::Any &aDialogSourceURL) throw ( ::com::sun::star::uno::Exception ); + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > createDialogModelForBasic() throw ( ::com::sun::star::uno::Exception ); + + // XDialogProvider / XDialogProvider2 impl method + virtual ::com::sun::star::uno::Reference < ::com::sun::star::awt::XControl > SAL_CALL createDialogImpl( + const ::rtl::OUString& URL, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xHandler, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParent, + bool bDialogProviderMode ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + public: + DialogProviderImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~DialogProviderImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XDialogProvider + virtual ::com::sun::star::uno::Reference < ::com::sun::star::awt::XDialog > SAL_CALL createDialog( + const ::rtl::OUString& URL ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XDialogProvider2 + virtual ::com::sun::star::uno::Reference < ::com::sun::star::awt::XDialog > SAL_CALL createDialogWithHandler( + const ::rtl::OUString& URL, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xHandler ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference < ::com::sun::star::awt::XDialog > SAL_CALL createDialogWithArguments( + const ::rtl::OUString& URL, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createContainerWindow( + const ::rtl::OUString& URL, const ::rtl::OUString& WindowType, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParent, + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xHandler ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + }; + +//......................................................................... +} // namespace dlgprov +//......................................................................... + +#endif // SCRIPTING_DLGPROV_HXX diff --git a/scripting/source/dlgprov/dlgprov.xml b/scripting/source/dlgprov/dlgprov.xml new file mode 100644 index 000000000000..556cc3fe2253 --- /dev/null +++ b/scripting/source/dlgprov/dlgprov.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name>dlgprov</module-name> + + <component-description> + <author>Thomas Benisch</author> + <name>com.sun.star.comp.scripting.DialogProvider</name> + <description>provider for dialogs</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="drafts"/> + <supported-service>com.sun.star.awt.DialogProvider</supported-service> + <type>com.sun.star.awt.XControl</type> + <type>com.sun.star.awt.XControlContainer</type> + <type>com.sun.star.awt.XDialog</type> + <type>com.sun.star.awt.XDialogProvider</type> + <type>com.sun.star.awt.XWindowPeer</type> + <type>com.sun.star.beans.XPropertySet</type> + <type>com.sun.star.frame.XModel</type> + <type>com.sun.star.io.XInputStreamProvider</type> + <type>com.sun.star.lang.IllegalArgumentException</type> + <type>com.sun.star.lang.XInitialization</type> + <type>com.sun.star.lang.XMultiComponentFactory</type> + <type>com.sun.star.lang.XServiceInfo</type> + <type>com.sun.star.reflection.InvocationTargetException</type> + <type>com.sun.star.script.CannotConvertException</type> + <type>com.sun.star.script.ScriptEventDescriptor</type> + <type>com.sun.star.script.XAllListener</type> + <type>com.sun.star.script.XEventAttacher</type> + <type>com.sun.star.script.XLibraryContainer</type> + <type>com.sun.star.script.XScriptEventsAttacher</type> + <type>com.sun.star.script.XScriptEventsSupplier</type> + <type>com.sun.star.script.XScriptListener</type> + <type>com.sun.star.uno.Exception</type> + <type>com.sun.star.uno.RuntimeException</type> + <type>com.sun.star.uno.XComponentContext</type> + <type>com.sun.star.script.provider.XScript</type> + <type>com.sun.star.script.provider.XScriptProvider</type> + <type> com.sun.star.uri.XUriReference </type> + <type> com.sun.star.uri.XUriReferenceFactory </type> + <type> com.sun.star.uri.XVndSunStarScriptUrl </type> + </component-description> + + <project-build-dependency>sfx2</project-build-dependency> + <project-build-dependency>xmlscript</project-build-dependency> + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + + <runtime-module-dependency>sfx2</runtime-module-dependency> + <runtime-module-dependency>xcr</runtime-module-dependency> + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> + +</module-description> diff --git a/scripting/source/dlgprov/makefile.mk b/scripting/source/dlgprov/makefile.mk new file mode 100644 index 000000000000..6c8ec298c760 --- /dev/null +++ b/scripting/source/dlgprov/makefile.mk @@ -0,0 +1,82 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=scripting +TARGET=dlgprov +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/dlgprov.obj \ + $(SLO)$/dlgevtatt.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX).uno +SHL1IMPLIB= i$(TARGET) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +SHL1STDLIBS= \ + $(SFX2LIB) \ + $(VCLLIB) \ + $(TOOLSLIB) \ + $(XMLSCRIPTLIB) \ + $(CPPUHELPERLIB) \ + $(COMPHELPERLIB) \ + $(UCBHELPERLIB) \ + $(CPPULIB) \ + $(BASICLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +# ------------------------------------------------------------------ + +ALLTAR : \ + $(MISC)$/$(TARGET).don \ + +$(SLOFILES) : $(MISC)$/$(TARGET).don + +$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb + +$(CPPUMAKER) -O$(INCCOM)$/$(TARGET) -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@ + echo $@ + diff --git a/scripting/source/inc/bcholder.hxx b/scripting/source/inc/bcholder.hxx new file mode 100644 index 000000000000..adb81074828a --- /dev/null +++ b/scripting/source/inc/bcholder.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_BCHOLDER_HXX +#define SCRIPTING_BCHOLDER_HXX + +#include <osl/mutex.hxx> +#include <cppuhelper/interfacecontainer.h> + + +//......................................................................... +namespace scripting_helper +{ +//......................................................................... + + // ---------------------------------------------------- + // class OMutexHolder + // ---------------------------------------------------- + + class OMutexHolder + { + protected: + ::osl::Mutex m_aMutex; + }; + + // ---------------------------------------------------- + // class OBroadcastHelperHolder + // ---------------------------------------------------- + + class OBroadcastHelperHolder + { + protected: + ::cppu::OBroadcastHelper m_aBHelper; + + public: + OBroadcastHelperHolder( ::osl::Mutex& rMutex ) : m_aBHelper( rMutex ) { } + + ::cppu::OBroadcastHelper& GetBroadcastHelper() { return m_aBHelper; } + const ::cppu::OBroadcastHelper& GetBroadcastHelper() const { return m_aBHelper; } + }; + +//......................................................................... +} // namespace scripting_helper +//......................................................................... + +#endif // SCRIPTING_BCHOLDER_HXX diff --git a/scripting/source/inc/util/MiscUtils.hxx b/scripting/source/inc/util/MiscUtils.hxx new file mode 100644 index 000000000000..fcb071700be0 --- /dev/null +++ b/scripting/source/inc/util/MiscUtils.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SCRIPT_FRAMEWORK_MISCUTILS_HXX_ +#define _SCRIPT_FRAMEWORK_MISCUTILS_HXX_ + +#include <rtl/ustring.hxx> +#include <tools/urlobj.hxx> + +#include <ucbhelper/content.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XTransientDocumentsDocumentContentFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> + + +#include "util.hxx" + +namespace sf_misc +{ +// for simplification +#define css ::com::sun::star + +class MiscUtils +{ +public: + static css::uno::Sequence< ::rtl::OUString > allOpenTDocUrls( const css::uno::Reference< css::uno::XComponentContext >& xCtx) +{ + css::uno::Sequence< ::rtl::OUString > result; + try + { + if ( !xCtx.is() ) + { + return result; + } + css::uno::Reference < css::lang::XMultiComponentFactory > xFac( xCtx->getServiceManager(), css::uno::UNO_QUERY ); + if ( xFac.is() ) + { + css::uno::Reference < com::sun::star::ucb::XSimpleFileAccess > xSFA( xFac->createInstanceWithContext( OUSTR("com.sun.star.ucb.SimpleFileAccess"), xCtx ), css::uno::UNO_QUERY ); + if ( xSFA.is() ) + { + result = xSFA->getFolderContents( OUSTR("vnd.sun.star.tdoc:/"), true ); + } + } + } + catch ( css::uno::Exception& ) + { + } + return result; +} + + static ::rtl::OUString xModelToTdocUrl( const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::uno::XComponentContext >& xContext ) +{ + css::uno::Reference< css::lang::XMultiComponentFactory > xMCF( + xContext->getServiceManager() ); + css::uno::Reference< + css::frame::XTransientDocumentsDocumentContentFactory > xDocFac; + try + { + xDocFac = + css::uno::Reference< + css::frame::XTransientDocumentsDocumentContentFactory >( + xMCF->createInstanceWithContext( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.frame.TransientDocumentsDocumentContentFactory" ) ), + xContext ), + css::uno::UNO_QUERY ); + } + catch ( css::uno::Exception const & ) + { + // handled below + } + + if ( xDocFac.is() ) + { + try + { + css::uno::Reference< css::ucb::XContent > xContent( + xDocFac->createDocumentContent( xModel ) ); + return xContent->getIdentifier()->getContentIdentifier(); + } + catch ( css::lang::IllegalArgumentException const & ) + { + OSL_ENSURE( false, "Invalid document model!" ); + } + } + + OSL_ENSURE( false, "Unable to obtain URL for document model!" ); + return rtl::OUString(); +} + static css::uno::Reference< css::frame::XModel > tDocUrlToModel( const ::rtl::OUString& url ) +{ + css::uno::Any result; + + try + { + ::ucbhelper::Content root( url, NULL ); + ::rtl::OUString propName = OUSTR("DocumentModel"); + result = getUCBProperty( root, propName ); + } + catch ( css::ucb::ContentCreationException& ) + { + // carry on, empty value will be returned + } + catch ( css::uno::RuntimeException& ) + { + // carry on, empty value will be returned + } + + css::uno::Reference< css::frame::XModel > xModel( + result, css::uno::UNO_QUERY ); + + return xModel; +} + + + static css::uno::Any getUCBProperty( ::ucbhelper::Content& content, ::rtl::OUString& prop ) +{ + css::uno::Any result; + try + { + result = content.getPropertyValue( prop ); + } + catch ( css::uno::Exception& ) + { + } + return result; +} + +private: +static ::rtl::OUString parseLocationName( const ::rtl::OUString& location ) +{ + // strip out the last leaf of location name + // e.g. file://dir1/dir2/Blah.sxw - > Blah.sxw + ::rtl::OUString temp = location; + INetURLObject aURLObj( temp ); + if ( !aURLObj.HasError() ) + temp = aURLObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); + return temp; +} + +}; +} // namespace sf_misc +#endif // diff --git a/scripting/source/inc/util/scriptingconstants.hxx b/scripting/source/inc/util/scriptingconstants.hxx new file mode 100644 index 000000000000..c390b4c815fe --- /dev/null +++ b/scripting/source/inc/util/scriptingconstants.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _COM_SUN_STAR_SCRIPTING_UTIL_SCRIPTINGCONSTANTS_HXX_ +#define _COM_SUN_STAR_SCRIPTING_UTIL_SCRIPTINGCONSTANTS_HXX_ + +namespace scripting_constants +{ + +class ScriptingConstantsPool +{ +public: + const ::rtl::OUString DOC_REF; + const ::rtl::OUString DOC_STORAGE_ID; + const ::rtl::OUString DOC_URI; + const ::rtl::OUString RESOLVED_STORAGE_ID; + const ::rtl::OUString SCRIPT_INFO; + const ::rtl::OUString SCRIPTSTORAGEMANAGER_SERVICE; + const sal_Int32 SHARED_STORAGE_ID; + const sal_Int32 USER_STORAGE_ID; + const sal_Int32 DOC_STORAGE_ID_NOT_SET; + + static ScriptingConstantsPool& instance() + { + static ScriptingConstantsPool *pPool = 0; + if( ! pPool ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! pPool ) + { + static ScriptingConstantsPool pool; + pPool = &pool; + } + } + return *pPool; + } +private: + ScriptingConstantsPool( const ScriptingConstantsPool & ); + ScriptingConstantsPool& operator = ( const ScriptingConstantsPool & ); + ScriptingConstantsPool() + : DOC_REF( RTL_CONSTASCII_USTRINGPARAM( "SCRIPTING_DOC_REF" ) ), + DOC_STORAGE_ID( RTL_CONSTASCII_USTRINGPARAM( + "SCRIPTING_DOC_STORAGE_ID" ) ), + DOC_URI( RTL_CONSTASCII_USTRINGPARAM( "SCRIPTING_DOC_URI" ) ), + RESOLVED_STORAGE_ID( RTL_CONSTASCII_USTRINGPARAM( + "SCRIPTING_RESOLVED_STORAGE_ID" ) ), + SCRIPT_INFO( RTL_CONSTASCII_USTRINGPARAM( "SCRIPT_INFO" ) ), + SCRIPTSTORAGEMANAGER_SERVICE( RTL_CONSTASCII_USTRINGPARAM( + "/singletons/com.sun.star.script.framework.storage.theScriptStorageManager" ) ), + SHARED_STORAGE_ID( 0 ), USER_STORAGE_ID( 1 ), + DOC_STORAGE_ID_NOT_SET( -1 ) + {} +}; + +} +#endif diff --git a/scripting/source/inc/util/util.hxx b/scripting/source/inc/util/util.hxx new file mode 100644 index 000000000000..27e5c19ccc91 --- /dev/null +++ b/scripting/source/inc/util/util.hxx @@ -0,0 +1,49 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _COM_SUN_STAR_SCRIPTING_UTIL_UTIL_HXX_ +#define _COM_SUN_STAR_SCRIPTING_UTIL_UTIL_HXX_ + +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> + +#define OUSTR(x) ::rtl::OUString( ::rtl::OUString::createFromAscii(x) ) + +namespace scripting_util +{ + inline void validateXRef(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRef, const sal_Char* Msg) throw (::com::sun::star::uno::RuntimeException) + { + OSL_ENSURE( xRef.is(), Msg ); + + if(!xRef.is()) + { + throw ::com::sun::star::uno::RuntimeException(OUSTR(Msg), ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >()); + } + } +} +#endif //_COM_SUN_STAR_SCRIPTING_UTIL_UTIL_HXX_ diff --git a/scripting/source/protocolhandler/exports.dxp b/scripting/source/protocolhandler/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/scripting/source/protocolhandler/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/scripting/source/protocolhandler/makefile.mk b/scripting/source/protocolhandler/makefile.mk new file mode 100644 index 000000000000..c782c1a188f5 --- /dev/null +++ b/scripting/source/protocolhandler/makefile.mk @@ -0,0 +1,63 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= scripting +TARGET= protocolhandler +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=\ + $(SLO)$/scripthandler.obj\ + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(SFXLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VCLLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/protocolhandler/protocolhandler.xml b/scripting/source/protocolhandler/protocolhandler.xml new file mode 100755 index 000000000000..f9b0df36895f --- /dev/null +++ b/scripting/source/protocolhandler/protocolhandler.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> ScriptProtocolHandler </module-name> + <component-description> + <author> Noel Power</author> + <name> com.sun.star.frame.ProtocolHandler</name> + <description> + This component is part of the Scripting Framework +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="com"/> + <supported-service> com.sun.star.frame.ProtocolHandler </supported-service> + <type> com.sun.star.frame.XDispatchProvider </type> + <type> com.sun.star.frame.XNotifyingDispatch </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.io.IOException </type> + <type> com.sun.star.uri.XUriReference </type> + <type> com.sun.star.uri.XUriReferenceFactory </type> + <type> com.sun.star.uri.XVndSunStarScriptUrl </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper2$(COM) </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx new file mode 100644 index 000000000000..1e6adb6e7804 --- /dev/null +++ b/scripting/source/protocolhandler/scripthandler.cxx @@ -0,0 +1,601 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "scripthandler.hxx" + +#include <osl/mutex.hxx> + +#include <com/sun/star/frame/DispatchResultEvent.hpp> +#include <com/sun/star/frame/DispatchResultState.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XModel.hpp> + +#include <com/sun/star/document/XEmbeddedScripts.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp> +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> + +#include <sfx2/objsh.hxx> +#include <sfx2/frame.hxx> +#include <sfx2/sfxdlg.hxx> +#include <vcl/abstdlg.hxx> + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <util/util.hxx> + +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "com/sun/star/uri/XUriReferenceFactory.hpp" +#include "com/sun/star/uri/XVndSunStarScriptUrl.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::script::provider; +using namespace ::com::sun::star::document; +using namespace ::scripting_util; + +namespace scripting_protocolhandler +{ + +const sal_Char * const MYSERVICENAME = "com.sun.star.frame.ProtocolHandler"; +const sal_Char * const MYIMPLNAME = "com.sun.star.comp.ScriptProtocolHandler"; +const sal_Char * MYSCHEME = "vnd.sun.star.script"; +const sal_Int32 MYSCHEME_LEN = 20; + +void SAL_CALL ScriptProtocolHandler::initialize( + const css::uno::Sequence < css::uno::Any >& aArguments ) + throw ( css::uno::Exception ) +{ + if ( m_bInitialised ) + { + return ; + } + + // first argument contains a reference to the frame (may be empty or the desktop, + // but usually it's a "real" frame) + if ( aArguments.getLength() && + sal_False == ( aArguments[ 0 ] >>= m_xFrame ) ) + { + ::rtl::OUString temp = OUSTR( "ScriptProtocolHandler::initialize: could not extract reference to the frame" ); + throw RuntimeException( temp, Reference< XInterface >() ); + } + + validateXRef( m_xFactory, + "ScriptProtocolHandler::initialize: No Service Manager available" ); + m_bInitialised = true; +} + +Reference< XDispatch > SAL_CALL ScriptProtocolHandler::queryDispatch( + const URL& aURL, const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags ) + throw( ::com::sun::star::uno::RuntimeException ) +{ + (void)sTargetFrameName; + (void)nSearchFlags; + + Reference< XDispatch > xDispatcher; + // get scheme of url + + Reference< uri::XUriReferenceFactory > xFac ( + m_xFactory->createInstance( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory") ) , UNO_QUERY ); + if ( xFac.is() ) + { + Reference< uri::XUriReference > uriRef( + xFac->parse( aURL.Complete ), UNO_QUERY ); + if ( uriRef.is() ) + { + if ( uriRef->getScheme().equals( ::rtl::OUString::createFromAscii( ::scripting_protocolhandler::MYSCHEME ) ) ) + { + xDispatcher = this; + } + } + } + + return xDispatcher; +} + +Sequence< Reference< XDispatch > > SAL_CALL +ScriptProtocolHandler::queryDispatches( +const Sequence < DispatchDescriptor >& seqDescriptor ) +throw( RuntimeException ) +{ + sal_Int32 nCount = seqDescriptor.getLength(); + Sequence< Reference< XDispatch > > lDispatcher( nCount ); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + lDispatcher[ i ] = this->queryDispatch( seqDescriptor[ i ].FeatureURL, + seqDescriptor[ i ].FrameName, + seqDescriptor[ i ].SearchFlags ); + } + return lDispatcher; +} + +void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( + const URL& aURL, const Sequence < PropertyValue >& lArgs, + const Reference< XDispatchResultListener >& xListener ) + throw ( RuntimeException ) +{ + + sal_Bool bSuccess = sal_False; + Any invokeResult; + bool bCaughtException = FALSE; + Any aException; + + if ( m_bInitialised ) + { + try + { + bool bIsDocumentScript = ( aURL.Complete.indexOf( ::rtl::OUString::createFromAscii( "document" ) ) !=-1 ); + // TODO: isn't this somewhat strange? This should be a test for a location=document parameter, shouldn't it? + + if ( bIsDocumentScript ) + { + // obtain the component for our security check + Reference< XEmbeddedScripts > xDocumentScripts; + if ( getScriptInvocation() ) + xDocumentScripts.set( m_xScriptInvocation->getScriptContainer(), UNO_SET_THROW ); + + OSL_ENSURE( xDocumentScripts.is(), "ScriptProtocolHandler::dispatchWithNotification: can't do the security check!" ); + if ( !xDocumentScripts.is() || !xDocumentScripts->getAllowMacroExecution() ) + return; + } + + // Creates a ScriptProvider ( if one is not created allready ) + createScriptProvider(); + + Reference< provider::XScript > xFunc = + m_xScriptProvider->getScript( aURL.Complete ); + validateXRef( xFunc, + "ScriptProtocolHandler::dispatchWithNotification: validate xFunc - unable to obtain XScript interface" ); + + + Sequence< Any > inArgs( 0 ); + Sequence< Any > outArgs( 0 ); + Sequence< sal_Int16 > outIndex; + + if ( lArgs.getLength() > 0 ) + { + int argCount = 0; + for ( int index = 0; index < lArgs.getLength(); index++ ) + { + // Sometimes we get a propertyval with name = "Referer" + // this is not an argument to be passed to script, so + // ignore. + if ( lArgs[ index ].Name.compareToAscii("Referer") != 0 || + lArgs[ index ].Name.getLength() == 0 ) + { + inArgs.realloc( ++argCount ); + inArgs[ argCount - 1 ] = lArgs[ index ].Value; + } + } + } + + bSuccess = sal_False; + while ( !bSuccess ) + { + Any aFirstCaughtException; + try + { + invokeResult = xFunc->invoke( inArgs, outIndex, outArgs ); + bSuccess = sal_True; + } + catch( const provider::ScriptFrameworkErrorException& se ) + { + if ( !aFirstCaughtException.hasValue() ) + aFirstCaughtException = ::cppu::getCaughtException(); + + if ( se.errorType != provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT ) + // the only condition which allows us to retry is if there is no method with the + // given name/signature + ::cppu::throwException( aFirstCaughtException ); + + if ( inArgs.getLength() == 0 ) + // no chance to retry if we can't strip more in-args + ::cppu::throwException( aFirstCaughtException ); + + // strip one argument, then retry + inArgs.realloc( inArgs.getLength() - 1 ); + } + } + } + // Office doesn't handle exceptions rethrown here very well, it cores, + // all we can is log them and then set fail for the dispatch event! + // (if there is a listener of course) + catch ( const Exception & e ) + { + aException = ::cppu::getCaughtException(); + + ::rtl::OUString reason = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScriptProtocolHandler::dispatch: caught " ) ); + + invokeResult <<= reason.concat( aException.getValueTypeName() ).concat( e.Message ); + + bCaughtException = TRUE; + } +#ifdef _DEBUG + catch ( ... ) + { + ::rtl::OUString reason = ::rtl::OUString::createFromAscii( + "ScriptProtocolHandler::dispatch: caught unknown exception" ); + + invokeResult <<= reason; + } +#endif + + } + else + { + ::rtl::OUString reason = ::rtl::OUString::createFromAscii( + "ScriptProtocolHandler::dispatchWithNotification failed, ScriptProtocolHandler not initialised" + ); + invokeResult <<= reason; + } + + if ( bCaughtException ) + { + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + if ( pFact != NULL ) + { + VclAbstractDialog* pDlg = + pFact->CreateScriptErrorDialog( NULL, aException ); + + if ( pDlg != NULL ) + { + pDlg->Execute(); + delete pDlg; + } + } + } + + if ( xListener.is() ) + { + // always call dispatchFinished(), because we didn't load a document but + // executed a macro instead! + ::com::sun::star::frame::DispatchResultEvent aEvent; + + aEvent.Source = static_cast< ::cppu::OWeakObject* >( this ); + aEvent.Result = invokeResult; + if ( bSuccess ) + { + aEvent.State = ::com::sun::star::frame::DispatchResultState::SUCCESS; + } + else + { + aEvent.State = ::com::sun::star::frame::DispatchResultState::FAILURE; + } + + try + { + xListener->dispatchFinished( aEvent ) ; + } + catch(RuntimeException & e) + { + OSL_TRACE( + "ScriptProtocolHandler::dispatchWithNotification: caught RuntimeException" + "while dispatchFinished %s", + ::rtl::OUStringToOString( e.Message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + } +} + +void SAL_CALL ScriptProtocolHandler::dispatch( +const URL& aURL, const Sequence< PropertyValue >& lArgs ) +throw ( RuntimeException ) +{ + dispatchWithNotification( aURL, lArgs, Reference< XDispatchResultListener >() ); +} + +void SAL_CALL ScriptProtocolHandler::addStatusListener( +const Reference< XStatusListener >& xControl, const URL& aURL ) +throw ( RuntimeException ) +{ + (void)xControl; + (void)aURL; + + // implement if status is supported +} + +void SAL_CALL ScriptProtocolHandler::removeStatusListener( +const Reference< XStatusListener >& xControl, const URL& aURL ) +throw ( RuntimeException ) +{ + (void)xControl; + (void)aURL; +} + +bool +ScriptProtocolHandler::getScriptInvocation() +{ + if ( !m_xScriptInvocation.is() && m_xFrame.is() ) + { + Reference< XController > xController = m_xFrame->getController(); + if ( xController .is() ) + { + // try to obtain an XScriptInvocationContext interface, preferred from the + // mode, then from the controller + if ( !m_xScriptInvocation.set( xController->getModel(), UNO_QUERY ) ) + m_xScriptInvocation.set( xController, UNO_QUERY ); + } + } + return m_xScriptInvocation.is(); +} + +void +ScriptProtocolHandler::createScriptProvider() +{ + if ( m_xScriptProvider.is() ) + { + return; + } + try + { + // first, ask the component supporting the XScriptInvocationContext interface + // (if there is one) for a script provider + if ( getScriptInvocation() ) + { + Reference< XScriptProviderSupplier > xSPS( m_xScriptInvocation, UNO_QUERY ); + if ( xSPS.is() ) + m_xScriptProvider = xSPS->getScriptProvider(); + } + + // second, ask the model in our frame + if ( !m_xScriptProvider.is() && m_xFrame.is() ) + { + Reference< XController > xController = m_xFrame->getController(); + if ( xController .is() ) + { + Reference< XScriptProviderSupplier > xSPS( xController->getModel(), UNO_QUERY ); + if ( xSPS.is() ) + m_xScriptProvider = xSPS->getScriptProvider(); + } + } + + + // as a fallback, ask the controller + if ( !m_xScriptProvider.is() && m_xFrame.is() ) + { + Reference< XScriptProviderSupplier > xSPS( m_xFrame->getController(), UNO_QUERY ); + if ( xSPS.is() ) + m_xScriptProvider = xSPS->getScriptProvider(); + } + + if ( !m_xScriptProvider.is() ) + { + Reference< XPropertySet > xProps( m_xFactory, UNO_QUERY_THROW ); + + ::rtl::OUString dc( + RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ); + + Reference< XComponentContext > xCtx( + xProps->getPropertyValue( dc ), UNO_QUERY_THROW ); + + ::rtl::OUString tmspf = ::rtl::OUString::createFromAscii( + "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory"); + + Reference< provider::XScriptProviderFactory > xFac( + xCtx->getValueByName( tmspf ), UNO_QUERY_THROW ); + + Any aContext; + if ( getScriptInvocation() ) + aContext = makeAny( m_xScriptInvocation ); + m_xScriptProvider = Reference< provider::XScriptProvider > ( + xFac->createScriptProvider( aContext ), UNO_QUERY_THROW ); + } + } + catch ( RuntimeException & e ) + { + ::rtl::OUString temp = OUSTR( "ScriptProtocolHandler::createScriptProvider(), " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + catch ( Exception & e ) + { + ::rtl::OUString temp = OUSTR( "ScriptProtocolHandler::createScriptProvider: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( + OUSTR( "ScriptProtocolHandler::createScriptProvider: UnknownException: " ), + Reference< XInterface > () ); + } +#endif + +} + +ScriptProtocolHandler::ScriptProtocolHandler( +Reference< css::lang::XMultiServiceFactory > const& rFact ) : +m_bInitialised( false ), m_xFactory( rFact ) +{ +} + +ScriptProtocolHandler::~ScriptProtocolHandler() +{ +} + +/* XServiceInfo */ +::rtl::OUString SAL_CALL ScriptProtocolHandler::getImplementationName( ) +throw( RuntimeException ) +{ + return impl_getStaticImplementationName(); +} + +/* XServiceInfo */ +sal_Bool SAL_CALL ScriptProtocolHandler::supportsService( +const ::rtl::OUString& sServiceName ) +throw( RuntimeException ) +{ + Sequence< ::rtl::OUString > seqServiceNames = getSupportedServiceNames(); + const ::rtl::OUString* pArray = seqServiceNames.getConstArray(); + for ( sal_Int32 nCounter = 0; nCounter < seqServiceNames.getLength(); nCounter++ ) + { + if ( pArray[ nCounter ] == sServiceName ) + { + return sal_True ; + } + } + + return sal_False ; +} + +/* XServiceInfo */ +Sequence< ::rtl::OUString > SAL_CALL ScriptProtocolHandler::getSupportedServiceNames() +throw( RuntimeException ) +{ + return impl_getStaticSupportedServiceNames(); +} + +/* Helper for XServiceInfo */ +Sequence< ::rtl::OUString > ScriptProtocolHandler::impl_getStaticSupportedServiceNames() +{ + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + Sequence< ::rtl::OUString > seqServiceNames( 1 ); + seqServiceNames.getArray() [ 0 ] = + ::rtl::OUString::createFromAscii( ::scripting_protocolhandler::MYSERVICENAME ); + return seqServiceNames ; +} + +/* Helper for XServiceInfo */ +::rtl::OUString ScriptProtocolHandler::impl_getStaticImplementationName() +{ + return ::rtl::OUString::createFromAscii( ::scripting_protocolhandler::MYIMPLNAME ); +} + +/* Helper for registry */ +Reference< XInterface > SAL_CALL ScriptProtocolHandler::impl_createInstance( +const Reference< css::lang::XMultiServiceFactory >& xServiceManager ) +throw( RuntimeException ) +{ + return Reference< XInterface > ( *new ScriptProtocolHandler( xServiceManager ) ); +} + +/* Factory for registration */ +Reference< XSingleServiceFactory > ScriptProtocolHandler::impl_createFactory( +const Reference< XMultiServiceFactory >& xServiceManager ) +{ + Reference< XSingleServiceFactory > xReturn ( + cppu::createSingleFactory( xServiceManager, + ScriptProtocolHandler::impl_getStaticImplementationName(), + ScriptProtocolHandler::impl_createInstance, + ScriptProtocolHandler::impl_getStaticSupportedServiceNames() ) + ); + return xReturn; +} + +} // namespace scripting_protocolhandler + +/* exported functions for registration */ +extern "C" +{ + +#undef css +#define css ::com::sun::star + + void SAL_CALL component_getImplementationEnvironment( + const sal_Char** ppEnvironmentTypeName, uno_Environment** ppEnvironment ) + { + (void)ppEnvironment; + + *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; + } + + sal_Bool SAL_CALL component_writeInfo( void * pServiceManager , + void * pRegistryKey ) + { + (void)pServiceManager; + + Reference< css::registry::XRegistryKey > xKey( + reinterpret_cast< css::registry::XRegistryKey* >( pRegistryKey ) ) ; + + ::rtl::OUString aStr = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); + aStr += + ::scripting_protocolhandler::ScriptProtocolHandler::impl_getStaticImplementationName(); + + aStr += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES" ) ); + Reference< css::registry::XRegistryKey > xNewKey = xKey->createKey( aStr ); + xNewKey->createKey( + ::rtl::OUString::createFromAscii( ::scripting_protocolhandler::MYSERVICENAME ) + ); + + return sal_True; + } + + void* SAL_CALL component_getFactory( const sal_Char * pImplementationName , + void * pServiceManager , + void * pRegistryKey ) + { + (void)pRegistryKey; + + // Set default return value for this operation - if it failed. + void * pReturn = NULL ; + + if ( + ( pImplementationName != NULL ) && + ( pServiceManager != NULL ) + ) + { + // Define variables which are used in following macros. + ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XSingleServiceFactory > xFactory ; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + xServiceManager( reinterpret_cast< + ::com::sun::star::lang::XMultiServiceFactory* >( pServiceManager ) ) ; + + if ( ::scripting_protocolhandler::ScriptProtocolHandler::impl_getStaticImplementationName().equals( + ::rtl::OUString::createFromAscii( pImplementationName ) ) ) + { + xFactory = ::scripting_protocolhandler::ScriptProtocolHandler::impl_createFactory( xServiceManager ); + } + + // Factory is valid - service was found. + if ( xFactory.is() ) + { + xFactory->acquire(); + pReturn = xFactory.get(); + } + } + + // Return with result of this operation. + return pReturn ; + } +} // extern "C" + + diff --git a/scripting/source/protocolhandler/scripthandler.hxx b/scripting/source/protocolhandler/scripthandler.hxx new file mode 100644 index 000000000000..164a8bcfe593 --- /dev/null +++ b/scripting/source/protocolhandler/scripthandler.hxx @@ -0,0 +1,151 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_SCRIPTHANDLER_HXX +#define _FRAMEWORK_SCRIPT_SCRIPTHANDLER_HXX + +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <cppuhelper/implbase4.hxx> +#include <com/sun/star/script/provider/XScriptProvider.hpp> + +namespace rtl +{ +class OUString; +} + +namespace com { namespace sun { namespace star { + + namespace document { + class XScriptInvocationContext; + } + namespace uno { + class Any; + } + namespace lang { + class XMultiServiceFactory; + class XSingleServiceFactory; + } + namespace frame { + class XFrame; + class XModel; + class XDispatch; + class XNotifyingDispatch; + class XDispatchResultListener; + struct DispatchDescriptor; + } + namespace beans { + struct PropertyValue; + } + namespace util { + struct URL; + } +} } } + +namespace scripting_protocolhandler +{ + +namespace css = ::com::sun::star; + +class ScriptProtocolHandler : +public ::cppu::WeakImplHelper4< css::frame::XDispatchProvider, + css::frame::XNotifyingDispatch, css::lang::XServiceInfo, css::lang::XInitialization > +{ +private: + bool m_bInitialised; + css::uno::Reference < css::lang::XMultiServiceFactory > m_xFactory; + css::uno::Reference < css::frame::XFrame > m_xFrame; + css::uno::Reference < css::script::provider::XScriptProvider > m_xScriptProvider; + css::uno::Reference< css::document::XScriptInvocationContext > m_xScriptInvocation; + + void createScriptProvider(); + bool getScriptInvocation(); + +public: + ScriptProtocolHandler( const css::uno::Reference < + css::lang::XMultiServiceFactory >& xFactory ); + virtual ~ScriptProtocolHandler(); + + /* XServiceInfo */ + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& sServiceName ) + throw( css::uno::RuntimeException ); + virtual css::uno::Sequence < ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw( css::uno::RuntimeException ); + + /* Helper for XServiceInfo */ + static css::uno::Sequence < ::rtl::OUString > impl_getStaticSupportedServiceNames(); + static ::rtl::OUString impl_getStaticImplementationName(); + + /* Helper for registry */ + static css::uno::Reference < css::uno::XInterface > SAL_CALL + impl_createInstance( + const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) + throw( css::uno::RuntimeException ); + static css::uno::Reference < css::lang::XSingleServiceFactory > impl_createFactory( + const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ); + + /* Implementation for XDispatchProvider */ + virtual css::uno::Reference < css::frame::XDispatch > SAL_CALL + queryDispatch( const css::util::URL& aURL, const ::rtl::OUString& sTargetFrameName, + sal_Int32 eSearchFlags ) throw( css::uno::RuntimeException ) ; + virtual css::uno::Sequence< css::uno::Reference < css::frame::XDispatch > > SAL_CALL + queryDispatches( + const css::uno::Sequence < css::frame::DispatchDescriptor >& seqDescriptor ) + throw( css::uno::RuntimeException ); + + /* Implementation for X(Notifying)Dispatch */ + virtual void SAL_CALL dispatchWithNotification( + const css::util::URL& aURL, + const css::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArgs, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchResultListener >& Listener ) + throw ( css::uno::RuntimeException ); + virtual void SAL_CALL dispatch( + const css::util::URL& aURL, + const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) + throw ( css::uno::RuntimeException ); + virtual void SAL_CALL addStatusListener( + const css::uno::Reference< css::frame::XStatusListener >& xControl, + const css::util::URL& aURL ) + throw ( css::uno::RuntimeException ); + virtual void SAL_CALL removeStatusListener( + const css::uno::Reference< css::frame::XStatusListener >& xControl, + const css::util::URL& aURL ) + throw ( css::uno::RuntimeException ); + + /* Implementation for XInitialization */ + virtual void SAL_CALL initialize( + const css::uno::Sequence < css::uno::Any >& aArguments ) + throw ( css::uno::Exception ); +}; + +} +#endif diff --git a/scripting/source/provider/ActiveMSPList.cxx b/scripting/source/provider/ActiveMSPList.cxx new file mode 100644 index 000000000000..3c6206d8d051 --- /dev/null +++ b/scripting/source/provider/ActiveMSPList.cxx @@ -0,0 +1,324 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <util/scriptingconstants.hxx> +#include <util/util.hxx> +#include <util/MiscUtils.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> + +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> + +#include "MasterScriptProvider.hxx" +#include "ActiveMSPList.hxx" + +#include <tools/diagnose_ex.h> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::script; +using namespace ::scripting_util; +using namespace ::sf_misc; + +namespace func_provider +{ + +ActiveMSPList::ActiveMSPList( const Reference< XComponentContext > & xContext ) : m_xContext( xContext ) +{ + userDirString = ::rtl::OUString::createFromAscii("user"); + shareDirString = ::rtl::OUString::createFromAscii("share"); + bundledDirString = ::rtl::OUString::createFromAscii("bundled"); +} + +ActiveMSPList::~ActiveMSPList() +{ +} + +Reference< provider::XScriptProvider > +ActiveMSPList::createNewMSP( const uno::Any& context ) +{ + ::rtl::OUString serviceName = ::rtl::OUString::createFromAscii("com.sun.star.script.provider.MasterScriptProvider"); + Sequence< Any > args( &context, 1 ); + + Reference< provider::XScriptProvider > msp( + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + serviceName, args, m_xContext ), UNO_QUERY ); + return msp; +} + +Reference< provider::XScriptProvider > +ActiveMSPList::getMSPFromAnyContext( const Any& aContext ) + SAL_THROW(( lang::IllegalArgumentException, RuntimeException )) +{ + Reference< provider::XScriptProvider > msp; + ::rtl::OUString sContext; + if ( aContext >>= sContext ) + { + msp = getMSPFromStringContext( sContext ); + return msp; + } + + Reference< frame::XModel > xModel( aContext, UNO_QUERY ); + + Reference< document::XScriptInvocationContext > xScriptContext( aContext, UNO_QUERY ); + if ( xScriptContext.is() ) + { + try + { + // the component supports executing scripts embedded in a - possibly foreign document. + // Check whether this other document its the component itself. + if ( !xModel.is() || ( xModel != xScriptContext->getScriptContainer() ) ) + { + msp = getMSPFromInvocationContext( xScriptContext ); + return msp; + } + } + catch( const lang::IllegalArgumentException& ) + { + xModel.set( Reference< frame::XModel >() ); + } + } + + if ( xModel.is() ) + { + sContext = MiscUtils::xModelToTdocUrl( xModel, m_xContext ); + msp = getMSPFromStringContext( sContext ); + return msp; + } + + createNonDocMSPs(); + return m_hMsps[ shareDirString ]; +} + +Reference< provider::XScriptProvider > + ActiveMSPList::getMSPFromInvocationContext( const Reference< document::XScriptInvocationContext >& xContext ) + SAL_THROW(( lang::IllegalArgumentException, RuntimeException )) +{ + Reference< provider::XScriptProvider > msp; + + Reference< document::XEmbeddedScripts > xScripts; + if ( xContext.is() ) + xScripts.set( xContext->getScriptContainer() ); + if ( !xScripts.is() ) + { + ::rtl::OUStringBuffer buf; + buf.appendAscii( "Failed to create MasterScriptProvider for ScriptInvocationContext: " ); + buf.appendAscii( "Component supporting XEmbeddScripts interface not found." ); + throw lang::IllegalArgumentException( buf.makeStringAndClear(), NULL, 1 ); + } + + ::osl::MutexGuard guard( m_mutex ); + + Reference< XInterface > xNormalized( xContext, UNO_QUERY ); + ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized ); + if ( pos == m_mScriptComponents.end() ) + { + // TODO + msp = createNewMSP( uno::makeAny( xContext ) ); + addActiveMSP( xNormalized, msp ); + } + else + { + msp = pos->second; + } + + return msp; +} + +Reference< provider::XScriptProvider > + ActiveMSPList::getMSPFromStringContext( const ::rtl::OUString& context ) + SAL_THROW(( lang::IllegalArgumentException, RuntimeException )) +{ + Reference< provider::XScriptProvider > msp; + try + { + if ( context.indexOf( OUSTR( "vnd.sun.star.tdoc" ) ) == 0 ) + { + Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( context ) ); + + Reference< document::XEmbeddedScripts > xScripts( xModel, UNO_QUERY ); + Reference< document::XScriptInvocationContext > xScriptsContext( xModel, UNO_QUERY ); + if ( !xScripts.is() && !xScriptsContext.is() ) + { + ::rtl::OUStringBuffer buf; + buf.appendAscii( "Failed to create MasterScriptProvider for '" ); + buf.append ( context ); + buf.appendAscii( "': Either XEmbeddScripts or XScriptInvocationContext need to be supported by the document." ); + throw lang::IllegalArgumentException( buf.makeStringAndClear(), NULL, 1 ); + } + + ::osl::MutexGuard guard( m_mutex ); + Reference< XInterface > xNormalized( xModel, UNO_QUERY ); + ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized ); + if ( pos == m_mScriptComponents.end() ) + { + msp = createNewMSP( context ); + addActiveMSP( xNormalized, msp ); + } + else + { + msp = pos->second; + } + } + else + { + ::osl::MutexGuard guard( m_mutex ); + Msp_hash::iterator h_itEnd = m_hMsps.end(); + Msp_hash::const_iterator itr = m_hMsps.find( context ); + if ( itr == h_itEnd ) + { + msp = createNewMSP( context ); + m_hMsps[ context ] = msp; + } + else + { + msp = m_hMsps[ context ]; + } + } + } + catch( const lang::IllegalArgumentException& ) + { + // allowed to leave + } + catch( const RuntimeException& ) + { + // allowed to leave + } + catch( const Exception& ) + { + ::rtl::OUStringBuffer aMessage; + aMessage.appendAscii( "Failed to create MasterScriptProvider for context '" ); + aMessage.append ( context ); + aMessage.appendAscii( "'." ); + throw lang::WrappedTargetRuntimeException( + aMessage.makeStringAndClear(), *this, ::cppu::getCaughtException() ); + } + return msp; +} + +void +ActiveMSPList::addActiveMSP( const Reference< uno::XInterface >& xComponent, + const Reference< provider::XScriptProvider >& msp ) +{ + ::osl::MutexGuard guard( m_mutex ); + Reference< XInterface > xNormalized( xComponent, UNO_QUERY ); + ScriptComponent_map::const_iterator pos = m_mScriptComponents.find( xNormalized ); + if ( pos == m_mScriptComponents.end() ) + { + m_mScriptComponents[ xNormalized ] = msp; + + // add self as listener for component disposal + // should probably throw from this method!!, reexamine + try + { + Reference< lang::XComponent > xBroadcaster = + Reference< lang::XComponent >( xComponent, UNO_QUERY_THROW ); + xBroadcaster->addEventListener( this ); + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } +} + +//************************************************************************* +void SAL_CALL +ActiveMSPList::disposing( const ::com::sun::star::lang::EventObject& Source ) +throw ( ::com::sun::star::uno::RuntimeException ) + +{ + try + { + Reference< XInterface > xNormalized( Source.Source, UNO_QUERY ); + if ( xNormalized.is() ) + { + ::osl::MutexGuard guard( m_mutex ); + ScriptComponent_map::iterator pos = m_mScriptComponents.find( xNormalized ); + if ( pos != m_mScriptComponents.end() ) + m_mScriptComponents.erase( pos ); + } + } + catch ( const Exception& ) + { + // if we get an exception here, there is not much we can do about + // it can't throw as it will screw up the model that is calling dispose + DBG_UNHANDLED_EXCEPTION(); + } +} + + +void +ActiveMSPList::createNonDocMSPs() +{ + static bool created = false; + if ( created ) + { + return; + } + else + { + ::osl::MutexGuard guard( m_mutex ); + if ( created ) + { + return; + } + // do creation of user and share MSPs here + ::rtl::OUString serviceName = ::rtl::OUString::createFromAscii("com.sun.star.script.provider.MasterScriptProvider"); + Sequence< Any > args(1); + + args[ 0 ] <<= userDirString; + Reference< provider::XScriptProvider > userMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY ); + // should check if provider reference is valid + m_hMsps[ userDirString ] = userMsp; + + args[ 0 ] <<= shareDirString; + Reference< provider::XScriptProvider > shareMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY ); + // should check if provider reference is valid + m_hMsps[ shareDirString ] = shareMsp; + + args[ 0 ] <<= bundledDirString; + Reference< provider::XScriptProvider > bundledMsp( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName, args, m_xContext ), UNO_QUERY ); + // should check if provider reference is valid + m_hMsps[ bundledDirString ] = bundledMsp; + + created = true; + } + +} + + +} // namespace func_provider + diff --git a/scripting/source/provider/ActiveMSPList.hxx b/scripting/source/provider/ActiveMSPList.hxx new file mode 100644 index 000000000000..b127f3c41b16 --- /dev/null +++ b/scripting/source/provider/ActiveMSPList.hxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _FRAMEWORK_SCRIPT_PROVIDER_OPENDOCUMENTLIST_HXX_ +#define _FRAMEWORK_SCRIPT_PROVIDER_OPENDOCUMENTLIST_HXX_ + +#include <hash_map> +#include <map> + +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/lang/XEventListener.hpp> + +#include <com/sun/star/script/provider/XScriptProvider.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> + +#include <comphelper/stl_types.hxx> + +namespace func_provider +{ +// for simplification +#define css ::com::sun::star + +//Typedefs +//============================================================================= + + +typedef ::std::map < css::uno::Reference< css::uno::XInterface > + , css::uno::Reference< css::script::provider::XScriptProvider > + , ::comphelper::OInterfaceCompare< css::uno::XInterface > + > ScriptComponent_map; + +typedef ::std::hash_map< ::rtl::OUString, + css::uno::Reference< css::script::provider::XScriptProvider >, + ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > Msp_hash; + +class ActiveMSPList : public ::cppu::WeakImplHelper1< css::lang::XEventListener > +{ + +public: + + ActiveMSPList( const css::uno::Reference< + css::uno::XComponentContext > & xContext ); + ~ActiveMSPList(); + + css::uno::Reference< css::script::provider::XScriptProvider > + getMSPFromStringContext( const ::rtl::OUString& context ) + SAL_THROW(( css::lang::IllegalArgumentException, css::uno::RuntimeException )); + + css::uno::Reference< css::script::provider::XScriptProvider > + getMSPFromAnyContext( const css::uno::Any& context ) + SAL_THROW(( css::lang::IllegalArgumentException, css::uno::RuntimeException )); + + css::uno::Reference< css::script::provider::XScriptProvider > + getMSPFromInvocationContext( const css::uno::Reference< css::document::XScriptInvocationContext >& context ) + SAL_THROW(( css::lang::IllegalArgumentException, css::uno::RuntimeException )); + + //XEventListener + //====================================================================== + + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) + throw ( css::uno::RuntimeException ); + +private: + void addActiveMSP( const css::uno::Reference< css::uno::XInterface >& xComponent, + const css::uno::Reference< css::script::provider::XScriptProvider >& msp ); + css::uno::Reference< css::script::provider::XScriptProvider > + createNewMSP( const css::uno::Any& context ); + css::uno::Reference< css::script::provider::XScriptProvider > + createNewMSP( const ::rtl::OUString& context ) + { + return createNewMSP( css::uno::makeAny( context ) ); + } + + void createNonDocMSPs(); + Msp_hash m_hMsps; + ScriptComponent_map m_mScriptComponents; + osl::Mutex m_mutex; + ::rtl::OUString userDirString; + ::rtl::OUString shareDirString; + ::rtl::OUString bundledDirString; + css::uno::Reference< css::uno::XComponentContext > m_xContext; +}; +} // func_provider +#endif diff --git a/scripting/source/provider/BrowseNodeFactoryImpl.cxx b/scripting/source/provider/BrowseNodeFactoryImpl.cxx new file mode 100644 index 000000000000..763b1d739d37 --- /dev/null +++ b/scripting/source/provider/BrowseNodeFactoryImpl.cxx @@ -0,0 +1,797 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/mediadescriptor.hxx> + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/reflection/XProxyFactory.hpp> + +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> + +#include <tools/diagnose_ex.h> + +#include "BrowseNodeFactoryImpl.hxx" +#include "ActiveMSPList.hxx" +#include <util/MiscUtils.hxx> +#include <util/util.hxx> + +#include <vector> +#include <algorithm> +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::sf_misc; + +namespace browsenodefactory +{ +class BrowseNodeAggregator : + public ::cppu::WeakImplHelper1< browse::XBrowseNode > +{ +private: + ::rtl::OUString m_Name; + Sequence< Reference< browse::XBrowseNode > > m_Nodes; + +public: + + BrowseNodeAggregator( const Reference< browse::XBrowseNode >& node ) + { + m_Name = node->getName(); + m_Nodes.realloc( 1 ); + m_Nodes[ 0 ] = node; + } + + ~BrowseNodeAggregator() + { + } + + void addBrowseNode( const Reference< browse::XBrowseNode>& node ) + { + sal_Int32 index = m_Nodes.getLength(); + + m_Nodes.realloc( index + 1 ); + m_Nodes[ index ] = node; + } + + virtual ::rtl::OUString + SAL_CALL getName() + throw ( RuntimeException ) + { + return m_Name; + } + + virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL + getChildNodes() + throw ( RuntimeException ) + { + std::vector< Sequence< Reference < browse::XBrowseNode > > > seqs; + seqs.reserve( m_Nodes.getLength() ); + + sal_Int32 numChildren = 0; + + for ( sal_Int32 i = 0; i < m_Nodes.getLength(); i++ ) + { + Sequence< Reference < browse::XBrowseNode > > childs; + try + { + childs = m_Nodes[ i ]->getChildNodes(); + seqs.push_back( childs ); + numChildren += childs.getLength(); + } + catch ( Exception& ) + { + // some form of exception getting child nodes so they + // won't be displayed + } + } + + std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it = seqs.begin(); + std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it_end = seqs.end(); + + Sequence< Reference < browse::XBrowseNode > > result( numChildren ); + for ( sal_Int32 index = 0; it != it_end && index < numChildren ; ++it ) + { + Sequence< Reference < browse::XBrowseNode > > childs = *it; + for ( sal_Int32 j = 0; j < childs.getLength(); j++ ) + { + result[ index++ ] = childs[ j ]; + } + } + return result; + } + + virtual sal_Bool SAL_CALL + hasChildNodes() + throw ( RuntimeException ) + { + if ( m_Nodes.getLength() != 0 ) + { + for ( sal_Int32 i = 0 ; i < m_Nodes.getLength(); i++ ) + { + try + { + if ( m_Nodes[ i ]->hasChildNodes() ) + { + return sal_True; + } + } + catch ( Exception& ) + { + // some form of exception getting child nodes so move + // on to the next one + } + } + } + + return sal_False; + } + + virtual sal_Int16 SAL_CALL getType() + throw ( RuntimeException ) + { + return browse::BrowseNodeTypes::CONTAINER; + } +}; + + +//typedef ::std::map< ::rtl::OUString, Reference< browse::XBrowseNode > > +typedef ::std::hash_map< ::rtl::OUString, Reference< browse::XBrowseNode >, + ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > + BrowseNodeAggregatorHash; +typedef ::std::vector< ::rtl::OUString > vString; + + +struct alphaSort +{ + bool operator()( const ::rtl::OUString& a, const ::rtl::OUString& b ) + { + return a.compareTo( b ) < 0; + } +}; +class LocationBrowseNode : + public ::cppu::WeakImplHelper1< browse::XBrowseNode > +{ +private: + BrowseNodeAggregatorHash* m_hBNA; + vString m_vStr; + ::rtl::OUString m_sNodeName; + Reference< browse::XBrowseNode > m_origNode; + +public: + + LocationBrowseNode( const Reference< browse::XBrowseNode >& node ) + { + m_sNodeName = node->getName(); + m_hBNA = NULL; + m_origNode.set( node ); + } + + ~LocationBrowseNode() + { + if (m_hBNA) + { + delete m_hBNA; + } + } + + // ------------------------------------------------------------------------- + // XBrowseNode + // ------------------------------------------------------------------------- + + virtual ::rtl::OUString SAL_CALL getName() + throw ( RuntimeException ) + { + return m_sNodeName; + } + + virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL + getChildNodes() + throw ( RuntimeException ) + { + if ( m_hBNA == NULL ) + { + loadChildNodes(); + } + + Sequence< Reference< browse::XBrowseNode > > children( m_hBNA->size() ); + sal_Int32 index = 0; + + vString::const_iterator it = m_vStr.begin(); + + for ( ; it != m_vStr.end(); ++it, index++ ) + { + children[ index ].set( m_hBNA->find( *it )->second ); + } + + return children; + } + + virtual sal_Bool SAL_CALL hasChildNodes() + throw ( RuntimeException ) + { + return sal_True; + } + + virtual sal_Int16 SAL_CALL getType() + throw ( RuntimeException ) + { + return browse::BrowseNodeTypes::CONTAINER; + } + +private: + + void loadChildNodes() + { + m_hBNA = new BrowseNodeAggregatorHash(); + + Sequence< Reference< browse::XBrowseNode > > langNodes = + m_origNode->getChildNodes(); + + for ( sal_Int32 i = 0; i < langNodes.getLength(); i++ ) + { + Reference< browse::XBrowseNode > xbn; + if ( langNodes[ i ]->getName().equals(::rtl::OUString::createFromAscii("uno_packages")) ) + { + xbn.set( new LocationBrowseNode( langNodes[ i ] ) ); + } + else + { + xbn.set( langNodes[ i ] ); + } + + Sequence< Reference< browse::XBrowseNode > > grandchildren = + xbn->getChildNodes(); + + for ( sal_Int32 j = 0; j < grandchildren.getLength(); j++ ) + { + Reference< browse::XBrowseNode > grandchild(grandchildren[j]); + + BrowseNodeAggregatorHash::iterator h_it = + m_hBNA->find( grandchild->getName() ); + + if ( h_it != m_hBNA->end() ) + { + BrowseNodeAggregator* bna = static_cast< BrowseNodeAggregator* >( h_it->second.get() ); + bna->addBrowseNode( grandchild ); + } + else + { + Reference< browse::XBrowseNode > bna( + new BrowseNodeAggregator( grandchild ) ); + (*m_hBNA)[ grandchild->getName() ].set( bna ); + m_vStr.push_back( grandchild->getName() ); + } + } + } + // sort children alpahbetically + ::std::sort( m_vStr.begin(), m_vStr.end(), alphaSort() ); + } +}; + +namespace +{ + +Sequence< Reference< browse::XBrowseNode > > getAllBrowseNodes( const Reference< XComponentContext >& xCtx ) +{ + Reference< lang::XMultiComponentFactory > mcf = + xCtx->getServiceManager(); + + Sequence< ::rtl::OUString > openDocs = + MiscUtils::allOpenTDocUrls( xCtx ); + + Reference< provider::XScriptProviderFactory > xFac; + sal_Int32 initialSize = openDocs.getLength() + 2; + sal_Int32 mspIndex = 0; + + Sequence < Reference < browse::XBrowseNode > > locnBNs( initialSize ); + try + { + xFac.set( + xCtx->getValueByName( + OUSTR("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW ); + + locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("user") ) ), UNO_QUERY_THROW ); + locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("share") ) ), UNO_QUERY_THROW ); + } + // TODO proper exception handling, should throw + catch( Exception& e ) + { + (void)e; + OSL_TRACE("Caught Exception %s", + ::rtl::OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + locnBNs.realloc( mspIndex ); + return locnBNs; + } + + for ( sal_Int32 i = 0; i < openDocs.getLength(); i++ ) + { + try + { + Reference< frame::XModel > model( MiscUtils::tDocUrlToModel( openDocs[ i ] ), UNO_QUERY_THROW ); + + // #i44599 Check if it's a real document or something special like Hidden/Preview + css::uno::Reference< css::frame::XController > xCurrentController = model->getCurrentController(); + if( xCurrentController.is() ) + { + comphelper::MediaDescriptor aMD( model->getArgs() ); + sal_Bool bDefault = false; + sal_Bool bHidden = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_HIDDEN(), bDefault ); + sal_Bool bPreview = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_PREVIEW(), bDefault ); + if( !bHidden && !bPreview ) + { + Reference< document::XEmbeddedScripts > xScripts( model, UNO_QUERY ); + if ( xScripts.is() ) + locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( + xFac->createScriptProvider( makeAny( model ) ), UNO_QUERY_THROW ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + } + + Sequence < Reference < browse::XBrowseNode > > locnBNs_Return( mspIndex ); + for ( sal_Int32 j = 0; j < mspIndex; j++ ) + locnBNs_Return[j] = locnBNs[j]; + + return locnBNs_Return; +} + +} // namespace + +typedef ::std::vector< Reference< browse::XBrowseNode > > vXBrowseNodes; + +struct alphaSortForBNodes +{ + bool operator()( const Reference< browse::XBrowseNode >& a, const Reference< browse::XBrowseNode >& b ) + { + return a->getName().compareTo( b->getName() ) < 0; + } +}; + +typedef ::cppu::WeakImplHelper1< browse::XBrowseNode > t_BrowseNodeBase; +class DefaultBrowseNode : + public t_BrowseNodeBase +{ + +private: + Reference< browse::XBrowseNode > m_xWrappedBrowseNode; + Reference< lang::XTypeProvider > m_xWrappedTypeProv; + Reference< XAggregation > m_xAggProxy; + Reference< XComponentContext > m_xCtx; + + DefaultBrowseNode(); +public: + DefaultBrowseNode( const Reference< XComponentContext >& xCtx, const Reference< browse::XBrowseNode>& xNode ) : m_xWrappedBrowseNode( xNode ), m_xWrappedTypeProv( xNode, UNO_QUERY ), m_xCtx( xCtx, UNO_QUERY ) + { + OSL_ENSURE( m_xWrappedBrowseNode.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" ); + OSL_ENSURE( m_xWrappedTypeProv.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" ); + OSL_ENSURE( m_xCtx.is(), "DefaultBrowseNode::DefaultBrowseNode(): No ComponentContext" ); + // Use proxy factory service to create aggregatable proxy. + try + { + Reference< lang::XMultiComponentFactory > xMFac( m_xCtx->getServiceManager(), UNO_QUERY_THROW ); + Reference< reflection::XProxyFactory > xProxyFac( + xMFac->createInstanceWithContext( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.reflection.ProxyFactory" ) ), + m_xCtx ), UNO_QUERY_THROW ); + m_xAggProxy = xProxyFac->createProxy( m_xWrappedBrowseNode ); + } + catch( uno::Exception& ) + { + OSL_ENSURE( false, "DefaultBrowseNode::DefaultBrowseNode: Caught exception!" ); + } + OSL_ENSURE( m_xAggProxy.is(), + "DefaultBrowseNode::DefaultBrowseNode: Wrapped BrowseNode cannot be aggregated!" ); + + if ( m_xAggProxy.is() ) + { + osl_incrementInterlockedCount( &m_refCount ); + + /* i35609 - Fix crash on Solaris. The setDelegator call needs + to be in its own block to ensure that all temporary Reference + instances that are acquired during the call are released + before m_refCount is decremented again */ + { + m_xAggProxy->setDelegator( + static_cast< cppu::OWeakObject * >( this ) ); + } + + osl_decrementInterlockedCount( &m_refCount ); + } + } + + ~DefaultBrowseNode() + { + if ( m_xAggProxy.is() ) + { + m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() ); + } + } + + virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL + getChildNodes() + throw ( RuntimeException ) + { + if ( hasChildNodes() ) + { + vXBrowseNodes m_vNodes; + Sequence < Reference< browse::XBrowseNode > > nodes = + m_xWrappedBrowseNode->getChildNodes(); + for ( sal_Int32 i=0; i<nodes.getLength(); i++ ) + { + Reference< browse::XBrowseNode > xBrowseNode = nodes[ i ]; + OSL_ENSURE( xBrowseNode.is(), "DefaultBrowseNode::getChildNodes(): Invalid BrowseNode" ); + if( xBrowseNode.is() ) + m_vNodes.push_back( new DefaultBrowseNode( m_xCtx, xBrowseNode ) ); + } + + ::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() ); + Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() ); + vXBrowseNodes::const_iterator it = m_vNodes.begin(); + for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it ) + { + children[ i ].set( *it ); + } + return children; + } + else + { + // no nodes + + Sequence < Reference< browse::XBrowseNode > > none; + return none; + } + } + + virtual sal_Int16 SAL_CALL getType() + throw ( RuntimeException ) + { + return m_xWrappedBrowseNode->getType(); + } + + virtual ::rtl::OUString + SAL_CALL getName() + throw ( RuntimeException ) + { + return m_xWrappedBrowseNode->getName(); + } + + virtual sal_Bool SAL_CALL + hasChildNodes() + throw ( RuntimeException ) + { + return m_xWrappedBrowseNode->hasChildNodes(); + } + + // XInterface + virtual Any SAL_CALL queryInterface( const Type& aType ) + throw ( com::sun::star::uno::RuntimeException ) + { + Any aRet = t_BrowseNodeBase::queryInterface( aType ); + if ( aRet.hasValue() ) + { + return aRet; + } + if ( m_xAggProxy.is() ) + { + return m_xAggProxy->queryAggregation( aType ); + } + else + { + return Any(); + } + } + + virtual void SAL_CALL acquire() + throw () + + { + osl_incrementInterlockedCount( &m_refCount ); + } + virtual void SAL_CALL release() + throw () + { + if ( osl_decrementInterlockedCount( &m_refCount ) == 0 ) + { + delete this; + } + } + // XTypeProvider (implemnented by base, but needs to be overridden for + // delegating to aggregate) + virtual Sequence< Type > SAL_CALL getTypes() + throw ( com::sun::star::uno::RuntimeException ) + { + return m_xWrappedTypeProv->getTypes(); + } + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() + throw ( com::sun::star::uno::RuntimeException ) + { + return m_xWrappedTypeProv->getImplementationId(); + + } +}; + +class DefaultRootBrowseNode : + public ::cppu::WeakImplHelper1< browse::XBrowseNode > +{ + +private: + vXBrowseNodes m_vNodes; + ::rtl::OUString m_Name; + + DefaultRootBrowseNode(); +public: + DefaultRootBrowseNode( const Reference< XComponentContext >& xCtx ) + { + Sequence < Reference< browse::XBrowseNode > > nodes = + getAllBrowseNodes( xCtx ); + + for ( sal_Int32 i=0; i<nodes.getLength(); i++ ) + { + m_vNodes.push_back( new DefaultBrowseNode( xCtx, nodes[ i ] ) ); + } + m_Name = ::rtl::OUString::createFromAscii( "Root" ); + } + + ~DefaultRootBrowseNode() + { + } + + virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL + getChildNodes() + throw ( RuntimeException ) + { + // no need to sort user, share, doc1...docN + //::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() ); + Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() ); + vXBrowseNodes::const_iterator it = m_vNodes.begin(); + for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it ) + { + children[ i ].set( *it ); + } + return children; + } + + virtual sal_Int16 SAL_CALL getType() + throw ( RuntimeException ) + { + return browse::BrowseNodeTypes::ROOT; + } + + virtual ::rtl::OUString + SAL_CALL getName() + throw ( RuntimeException ) + { + return m_Name; + } + + virtual sal_Bool SAL_CALL + hasChildNodes() + throw ( RuntimeException ) + { + sal_Bool result = sal_True; + if ( !m_vNodes.size() ) + { + result = sal_False; + } + return result; + } +}; + + +class SelectorBrowseNode : + public ::cppu::WeakImplHelper1< browse::XBrowseNode > +{ +private: + Reference< XComponentContext > m_xComponentContext; + +public: + SelectorBrowseNode( const Reference< XComponentContext >& xContext ) + : m_xComponentContext( xContext ) + { + } + + ~SelectorBrowseNode() + { + } + + virtual ::rtl::OUString SAL_CALL getName() + throw ( RuntimeException ) + { + return ::rtl::OUString::createFromAscii( "Root" ); + } + + virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL + getChildNodes() + throw ( RuntimeException ) + { + + Sequence < Reference < browse::XBrowseNode > > locnBNs = getAllBrowseNodes( m_xComponentContext ); + + Sequence< Reference< browse::XBrowseNode > > children( + locnBNs.getLength() ); + + for ( sal_Int32 j = 0; j < locnBNs.getLength(); j++ ) + { + children[j] = new LocationBrowseNode( locnBNs[j] ); + } + + return children; + } + + virtual sal_Bool SAL_CALL hasChildNodes() + throw ( RuntimeException ) + { + return sal_True; // will always be user and share + } + + virtual sal_Int16 SAL_CALL getType() + throw ( RuntimeException ) + { + return browse::BrowseNodeTypes::CONTAINER; + } +}; + +BrowseNodeFactoryImpl::BrowseNodeFactoryImpl( + Reference< XComponentContext > const & xComponentContext ) + : m_xComponentContext( xComponentContext ) +{ +} + +BrowseNodeFactoryImpl::~BrowseNodeFactoryImpl() +{ +} + + +//############################################################################ +// Implementation of XBrowseNodeFactory +//############################################################################ + +/* + * The selector hierarchy is the standard hierarchy for organizers with the + * language nodes removed. + */ +Reference< browse::XBrowseNode > SAL_CALL +BrowseNodeFactoryImpl::createView( sal_Int16 viewType ) + throw (RuntimeException) +{ + switch( viewType ) + { + case browse::BrowseNodeFactoryViewTypes::MACROSELECTOR: + return getSelectorHierarchy(); + case browse::BrowseNodeFactoryViewTypes::MACROORGANIZER: + return getOrganizerHierarchy(); + default: + throw RuntimeException( OUSTR("Unknown view type" ), Reference< XInterface >() ); + } +} + +Reference< browse::XBrowseNode > +BrowseNodeFactoryImpl::getSelectorHierarchy() + throw (RuntimeException) +{ + /*if ( !m_xSelectorBrowseNode.is() ) + { + m_xSelectorBrowseNode = new SelectorBrowseNode( m_xComponentContext ); + }*/ + return new SelectorBrowseNode( m_xComponentContext ); +} + +Reference< browse::XBrowseNode > +BrowseNodeFactoryImpl::getOrganizerHierarchy() + throw (RuntimeException) +{ + Reference< browse::XBrowseNode > xRet = new DefaultRootBrowseNode( m_xComponentContext ); + return xRet; +} +//############################################################################ +// Helper methods +//############################################################################ + +//############################################################################ +// Namespace global methods for setting up BrowseNodeFactory service +//############################################################################ + +Sequence< ::rtl::OUString > SAL_CALL +bnf_getSupportedServiceNames( ) + SAL_THROW( () ) +{ + ::rtl::OUString str_name = ::rtl::OUString::createFromAscii( + "com.sun.star.script.browse.BrowseNodeFactory"); + + return Sequence< ::rtl::OUString >( &str_name, 1 ); +} + +::rtl::OUString SAL_CALL +bnf_getImplementationName( ) + SAL_THROW( () ) +{ + return ::rtl::OUString::createFromAscii( + "com.sun.star.script.browse.BrowseNodeFactory" ); +} + +Reference< XInterface > SAL_CALL +bnf_create( Reference< XComponentContext > const & xComponentContext ) + SAL_THROW( (Exception) ) +{ + return static_cast< ::cppu::OWeakObject * >( + new BrowseNodeFactoryImpl( xComponentContext ) ); +} + +//############################################################################ +// Implementation of XServiceInfo +//############################################################################ + +::rtl::OUString SAL_CALL +BrowseNodeFactoryImpl::getImplementationName() + throw (RuntimeException) +{ + return bnf_getImplementationName(); +} + +Sequence< ::rtl::OUString > SAL_CALL +BrowseNodeFactoryImpl::getSupportedServiceNames() + throw (RuntimeException) +{ + return bnf_getSupportedServiceNames(); +} + +sal_Bool BrowseNodeFactoryImpl::supportsService( + ::rtl::OUString const & serviceName ) + throw (RuntimeException) +{ +// check(); + + Sequence< ::rtl::OUString > supported_services( + getSupportedServiceNames() ); + + ::rtl::OUString const * ar = supported_services.getConstArray(); + + for ( sal_Int32 pos = supported_services.getLength(); pos--; ) + { + if (ar[ pos ].equals( serviceName )) + return sal_True; + } + return sal_False; +} + +} // namespace browsenodefactory diff --git a/scripting/source/provider/BrowseNodeFactoryImpl.hxx b/scripting/source/provider/BrowseNodeFactoryImpl.hxx new file mode 100644 index 000000000000..29a97e2f2bf5 --- /dev/null +++ b/scripting/source/provider/BrowseNodeFactoryImpl.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase2.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <com/sun/star/script/browse/XBrowseNode.hpp> +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp> + +namespace browsenodefactory +{ +// for simplification +#define css ::com::sun::star + +class BrowseNodeFactoryImpl : + public ::cppu::WeakImplHelper2 < + css::script::browse::XBrowseNodeFactory, + css::lang::XServiceInfo > +{ +private: + css::uno::Reference< css::uno::XComponentContext > m_xComponentContext; + css::uno::Reference< css::script::browse::XBrowseNode > m_xSelectorBrowseNode; + +protected: + virtual ~BrowseNodeFactoryImpl(); + +public: + BrowseNodeFactoryImpl( + css::uno::Reference< css::uno::XComponentContext > const & xComponentContext ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw ( css::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( ::rtl::OUString const & serviceName ) + throw ( css::uno::RuntimeException ); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw ( css::uno::RuntimeException ); + + // XBrowseNodeFactory + virtual css::uno::Reference< css::script::browse::XBrowseNode > SAL_CALL + createView( sal_Int16 viewType ) + throw ( css::uno::RuntimeException ); + private: + css::uno::Reference< css::script::browse::XBrowseNode > + getSelectorHierarchy() + throw ( css::uno::RuntimeException ); + + css::uno::Reference< css::script::browse::XBrowseNode > + getOrganizerHierarchy() + throw ( css::uno::RuntimeException ); +}; + + +} // namespace browsenodefactory diff --git a/scripting/source/provider/MasterScriptProvider.cxx b/scripting/source/provider/MasterScriptProvider.cxx new file mode 100755 index 000000000000..dbade7172e6e --- /dev/null +++ b/scripting/source/provider/MasterScriptProvider.cxx @@ -0,0 +1,1037 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <comphelper/documentinfo.hxx> + +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/EventObject.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> + +#include <com/sun/star/uri/XUriReference.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> + +#include <com/sun/star/deployment/XPackage.hpp> +#include <com/sun/star/script/browse/BrowseNodeTypes.hpp> +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> + +#include <util/scriptingconstants.hxx> +#include <util/util.hxx> +#include <util/MiscUtils.hxx> + +#include "ActiveMSPList.hxx" +#include "MasterScriptProvider.hxx" +#include "URIHelper.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::document; +using namespace ::sf_misc; +using namespace ::scripting_util; + +namespace func_provider +{ +//************************************************************************* +// Definitions for MasterScriptProviderFactory global methods. +//************************************************************************* + +::rtl::OUString SAL_CALL mspf_getImplementationName() ; +Reference< XInterface > SAL_CALL mspf_create( Reference< XComponentContext > const & xComponentContext ); +Sequence< ::rtl::OUString > SAL_CALL mspf_getSupportedServiceNames(); + + +bool endsWith( const ::rtl::OUString& target, + const ::rtl::OUString& item ) +{ + sal_Int32 index = 0; + if ( ( index = target.indexOf( item ) ) != -1 && + ( index == ( target.getLength() - item.getLength() ) ) ) + { + return true; + } + return false; +} +//::rtl_StandardModuleCount s_moduleCount = MODULE_COUNT_INIT; + +/* should be available in some central location. */ +//************************************************************************* +// XScriptProvider implementation +// +//************************************************************************* +MasterScriptProvider::MasterScriptProvider( const Reference< XComponentContext > & xContext ) throw ( RuntimeException ): + m_xContext( xContext ), m_bIsValid( false ), m_bInitialised( false ), + m_bIsPkgMSP( false ), m_pPCache( 0 ) +{ + validateXRef( m_xContext, "MasterScriptProvider::MasterScriptProvider: No context available\n" ); + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, + "MasterScriptProvider::MasterScriptProvider: No service manager available\n" ); + m_bIsValid = true; +} + +//************************************************************************* +MasterScriptProvider::~MasterScriptProvider() +{ + //s_moduleCount.modCnt.release( &s_moduleCount.modCnt ); + if ( m_pPCache ) + { + delete m_pPCache; + } + m_pPCache = 0; +} + +//************************************************************************* +void SAL_CALL MasterScriptProvider::initialize( const Sequence < Any >& args ) +throw ( Exception, RuntimeException ) +{ + if ( m_bInitialised ) + return; + + m_bIsValid = false; + + sal_Int32 len = args.getLength(); + if ( len > 1 ) + { + throw RuntimeException( + OUSTR( "MasterScriptProvider::initialize: invalid number of arguments" ), + Reference< XInterface >() ); + } + + Sequence< Any > invokeArgs( len ); + + if ( len != 0 ) + { + // check if first parameter is a string + // if it is, this implies that this is a MSP created + // with a user or share ctx ( used for browse functionality ) + // + if ( args[ 0 ] >>= m_sCtxString ) + { + invokeArgs[ 0 ] = args[ 0 ]; + if ( m_sCtxString.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.tdoc" ) ) == 0 ) + { + m_xModel = MiscUtils::tDocUrlToModel( m_sCtxString ); + } + } + else if ( args[ 0 ] >>= m_xInvocationContext ) + { + m_xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY_THROW ); + } + else + { + args[ 0 ] >>= m_xModel; + } + + if ( m_xModel.is() ) + { + // from the arguments, we were able to deduce a model. That alone doesn't + // suffice, we also need an XEmbeddedScripts which actually indicates support + // for embeddeding scripts + Reference< XEmbeddedScripts > xScripts( m_xModel, UNO_QUERY ); + if ( !xScripts.is() ) + { + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "The given document does not support embedding scripts into it, and cannot be associated with such a document." + ) ), + *this, + 1 + ); + } + + try + { + m_sCtxString = MiscUtils::xModelToTdocUrl( m_xModel, m_xContext ); + } + catch ( const Exception& ) + { + Any aError( ::cppu::getCaughtException() ); + + ::rtl::OUStringBuffer buf; + buf.appendAscii( "MasterScriptProvider::initialize: caught " ); + buf.append ( aError.getValueTypeName() ); + buf.appendAscii( ":" ); + + Exception aException; aError >>= aException; + buf.append ( aException.Message ); + throw lang::WrappedTargetException( buf.makeStringAndClear(), *this, aError ); + } + + if ( m_xInvocationContext.is() && m_xInvocationContext != m_xModel ) + invokeArgs[ 0 ] <<= m_xInvocationContext; + else + invokeArgs[ 0 ] <<= m_sCtxString; + } + + ::rtl::OUString pkgSpec = OUSTR("uno_packages"); + sal_Int32 indexOfPkgSpec = m_sCtxString.lastIndexOf( pkgSpec ); + + // if contex string ends with "uno_packages" + if ( indexOfPkgSpec > -1 && ( m_sCtxString.match( pkgSpec, indexOfPkgSpec ) == sal_True ) ) + { + m_bIsPkgMSP = sal_True; + } + else + { + m_bIsPkgMSP = sal_False; + } + } + else // no args + { + // use either scriping context or maybe zero args? + invokeArgs = Sequence< Any >( 0 ); // no arguments + } + m_sAargs = invokeArgs; + // don't create pkg mgr MSP for documents, not supported + if ( m_bIsPkgMSP == sal_False && !m_xModel.is() ) + { + createPkgProvider(); + } + + m_bInitialised = true; + m_bIsValid = true; +} + + +//************************************************************************* +void MasterScriptProvider::createPkgProvider() +{ + try + { + ::rtl::OUString loc = m_sCtxString; + Any location; + ::rtl::OUString sPkgCtx = m_sCtxString.concat( OUSTR(":uno_packages") ); + location <<= sPkgCtx; + + Reference< provider::XScriptProviderFactory > xFac( + m_xContext->getValueByName( + OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW ); + + m_xMSPPkg.set( + xFac->createScriptProvider( location ), UNO_QUERY_THROW ); + + } + catch ( Exception& e ) + { + (void)e; + OSL_TRACE("Exception creating MasterScriptProvider for uno_packages in context %s: %s", + ::rtl::OUStringToOString( m_sCtxString, + RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( e.Message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } +} + +//************************************************************************* +Reference< provider::XScript > +MasterScriptProvider::getScript( const ::rtl::OUString& scriptURI ) +throw ( provider::ScriptFrameworkErrorException, + RuntimeException ) +{ + if ( !isValid() ) + { + throw provider::ScriptFrameworkErrorException( + OUSTR( "MasterScriptProvider not initialised" ), Reference< XInterface >(), + scriptURI, OUSTR(""), + provider::ScriptFrameworkErrorType::UNKNOWN ); + } + + // need to get the language from the string + + Reference< uri::XUriReferenceFactory > xFac ( + m_xMgr->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); + if ( !xFac.is() ) + { + ::rtl::OUString message = ::rtl::OUString::createFromAscii("Failed to instantiate UriReferenceFactory"); + throw provider::ScriptFrameworkErrorException( + message, Reference< XInterface >(), + scriptURI, ::rtl::OUString(), + provider::ScriptFrameworkErrorType::UNKNOWN ); + } + + Reference< uri::XUriReference > uriRef( + xFac->parse( scriptURI ), UNO_QUERY ); + + Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY ); + + if ( !uriRef.is() || !sfUri.is() ) + { + ::rtl::OUString errorMsg = OUSTR( "Incorrect format for Script URI: " ); + errorMsg = errorMsg.concat( scriptURI ); + throw provider::ScriptFrameworkErrorException( + errorMsg, Reference< XInterface >(), + scriptURI, OUSTR(""), + provider::ScriptFrameworkErrorType::UNKNOWN ); + } + + ::rtl::OUString langKey = ::rtl::OUString::createFromAscii( "language" ); + ::rtl::OUString locKey = ::rtl::OUString::createFromAscii( "location" ); + + if ( sfUri->hasParameter( langKey ) == sal_False || + sfUri->hasParameter( locKey ) == sal_False || + ( sfUri->getName().getLength() == 0 ) ) + { + ::rtl::OUString errorMsg = OUSTR( "Incorrect format for Script URI: " ); + errorMsg = errorMsg.concat( scriptURI ); + throw provider::ScriptFrameworkErrorException( + errorMsg, Reference< XInterface >(), + scriptURI, OUSTR(""), + provider::ScriptFrameworkErrorType::UNKNOWN ); + } + + ::rtl::OUString language = sfUri->getParameter( langKey ); + ::rtl::OUString location = sfUri->getParameter( locKey ); + + // if script us located in uno pkg + sal_Int32 index = -1; + ::rtl::OUString pkgTag = + ::rtl::OUString::createFromAscii( ":uno_packages" ); + // for languages other than basic, scripts located in uno packages + // are merged into the user/share location context. + // For other languages the location attribute in script url has the form + // location = [user|share]:uno_packages or location :uno_pacakges/xxxx.uno.pkg + // we need to extract the value of location part from the + // location attribute of the script, if the script is located in an + // uno package then that is the location part up to and including + // ":uno_packages", if the script is not in an uno package then the + // normal value is used e.g. user or share. + // The value extracted will be used to determine if the script is + // located in the same location context as this MSP. + // For Basic, the language script provider can handle the execution of a + // script in any location context + if ( ( index = location.indexOf( pkgTag ) ) > -1 ) + { + location = location.copy( 0, index + pkgTag.getLength() ); + } + + Reference< provider::XScript > xScript; + + // If the script location is in the same location context as this + // MSP then delate to the lanaguage provider controlled by this MSP + // ** Special case is BASIC, all calls to getScript will be handled + // by the language script provider in the current location context + // even if its different + if ( ( location.equals( OUSTR( "document" ) ) + && m_xModel.is() + ) + || ( endsWith( m_sCtxString, location ) ) + || ( language.equals( OUSTR( "Basic" ) ) ) + ) + { + Reference< provider::XScriptProvider > xScriptProvider; + ::rtl::OUStringBuffer buf( 80 ); + buf.appendAscii( "com.sun.star.script.provider.ScriptProviderFor"); + buf.append( language ); + ::rtl::OUString serviceName = buf.makeStringAndClear(); + if ( providerCache() ) + { + try + { + xScriptProvider.set( + providerCache()->getProvider( serviceName ), + UNO_QUERY_THROW ); + } + catch( const Exception& e ) + { + throw provider::ScriptFrameworkErrorException( + e.Message, Reference< XInterface >(), + sfUri->getName(), language, + provider::ScriptFrameworkErrorType::NOTSUPPORTED ); + } + } + else + { + throw provider::ScriptFrameworkErrorException( + OUSTR( "No LanguageProviders detected" ), + Reference< XInterface >(), + sfUri->getName(), language, + provider::ScriptFrameworkErrorType::NOTSUPPORTED ); + } + xScript=xScriptProvider->getScript( scriptURI ); + } + else + { + Reference< provider::XScriptProviderFactory > xFac_( + m_xContext->getValueByName( + OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW ); + + Reference< provider::XScriptProvider > xSP( + xFac_->createScriptProvider( makeAny( location ) ), UNO_QUERY_THROW ); + xScript = xSP->getScript( scriptURI ); + } + + return xScript; +} +//************************************************************************* +bool +MasterScriptProvider::isValid() +{ + return m_bIsValid; +} + +//************************************************************************* +ProviderCache* +MasterScriptProvider::providerCache() +{ + if ( !m_pPCache ) + { + ::osl::MutexGuard aGuard( m_mutex ); + if ( !m_pPCache ) + { + ::rtl::OUString serviceName1 = OUSTR("com.sun.star.script.provider.ScriptProviderForBasic"); + Sequence< ::rtl::OUString > blacklist(1); + blacklist[ 0 ] = serviceName1; + + if ( !m_bIsPkgMSP ) + { + m_pPCache = new ProviderCache( m_xContext, m_sAargs ); + } + else + { + m_pPCache = new ProviderCache( m_xContext, m_sAargs, blacklist ); + } + } + } + return m_pPCache; +} + + +//************************************************************************* +::rtl::OUString SAL_CALL +MasterScriptProvider::getName() + throw ( css::uno::RuntimeException ) +{ + if ( !isPkgProvider() ) + { + ::rtl::OUString sCtx = getContextString(); + if ( sCtx.indexOf( OUSTR( "vnd.sun.star.tdoc" ) ) == 0 ) + { + Reference< frame::XModel > xModel = m_xModel; + if ( !xModel.is() ) + { + xModel = MiscUtils::tDocUrlToModel( sCtx ); + } + + m_sNodeName = ::comphelper::DocumentInfo::getDocumentTitle( xModel ); + } + else + { + m_sNodeName = parseLocationName( getContextString() ); + } + } + else + { + m_sNodeName = OUSTR("uno_packages"); + } + return m_sNodeName; +} + +//************************************************************************* +Sequence< Reference< browse::XBrowseNode > > SAL_CALL +MasterScriptProvider::getChildNodes() + throw ( css::uno::RuntimeException ) +{ + Sequence< Reference< provider::XScriptProvider > > providers = getAllProviders(); + + Reference< provider::XScriptProvider > pkgProv = getPkgProvider(); + sal_Int32 size = providers.getLength(); + bool hasPkgs = pkgProv.is(); + if ( hasPkgs ) + { + size++; + } + Sequence< Reference< browse::XBrowseNode > > children( size ); + sal_Int32 provIndex = 0; + for ( ; provIndex < providers.getLength(); provIndex++ ) + { + children[ provIndex ] = Reference< browse::XBrowseNode >( providers[ provIndex ], UNO_QUERY ); + } + + if ( hasPkgs ) + { + children[ provIndex ] = Reference< browse::XBrowseNode >( pkgProv, UNO_QUERY ); + + } + + return children; +} + +//************************************************************************* +sal_Bool SAL_CALL +MasterScriptProvider::hasChildNodes() + throw ( css::uno::RuntimeException ) +{ + return sal_True; +} + +//************************************************************************* +sal_Int16 SAL_CALL +MasterScriptProvider::getType() + throw ( css::uno::RuntimeException ) +{ + return browse::BrowseNodeTypes::CONTAINER; +} + +//************************************************************************* + +::rtl::OUString +MasterScriptProvider::parseLocationName( const ::rtl::OUString& location ) +{ + // strip out the last leaf of location name + // e.g. file://dir1/dir2/Blah.sxw - > Blah.sxw + ::rtl::OUString temp = location; + INetURLObject aURLObj( temp ); + if ( !aURLObj.HasError() ) + temp = aURLObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); + return temp; +} + +//************************************************************************* +// Register Package +void SAL_CALL +MasterScriptProvider::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw ( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, css::uno::RuntimeException) +{ + if ( !m_bIsPkgMSP ) + { + if ( m_xMSPPkg.is() ) + { + Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY ); + if ( !xCont.is() ) + { + throw RuntimeException( + OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"), + Reference< XInterface >() ); + } + xCont->insertByName( aName, aElement ); + } + else + { + throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"), + Reference< XInterface >() ); + } + + } + else + { + Reference< deployment::XPackage > xPkg( aElement, UNO_QUERY ); + if ( !xPkg.is() ) + { + throw lang::IllegalArgumentException( OUSTR("Couldn't convert to XPackage"), + Reference < XInterface > (), 2 ); + } + if ( !aName.getLength() ) + { + throw lang::IllegalArgumentException( OUSTR("Name not set!!"), + Reference < XInterface > (), 1 ); + } + // TODO for library pacakge parse the language, for the moment will try + // to get each provider to process the new Package, the first one the succeeds + // will terminate processing + if ( !providerCache() ) + { + throw RuntimeException( + OUSTR("insertByName cannot instantiate " + "child script providers."), + Reference< XInterface >() ); + } + Sequence < Reference< provider::XScriptProvider > > xSProviders = + providerCache()->getAllProviders(); + sal_Int32 index = 0; + + for ( ; index < xSProviders.getLength(); index++ ) + { + Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY ); + if ( !xCont.is() ) + { + continue; + } + try + { + xCont->insertByName( aName, aElement ); + break; + } + catch ( Exception& ) + { + } + + } + if ( index == xSProviders.getLength() ) + { + // No script providers could process the package + ::rtl::OUString message = OUSTR("Failed to register package for "); + message = message.concat( aName ); + throw lang::IllegalArgumentException( message, + Reference < XInterface > (), 2 ); + } + } +} + +//************************************************************************* +// Revoke Package +void SAL_CALL +MasterScriptProvider::removeByName( const ::rtl::OUString& Name ) throw ( container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + if ( !m_bIsPkgMSP ) + { + if ( m_xMSPPkg.is() ) + { + Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY ); + if ( !xCont.is() ) + { + throw RuntimeException( + OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"), + Reference< XInterface >() ); + } + xCont->removeByName( Name ); + } + else + { + throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"), + Reference< XInterface >() ); + } + + } + else + { + if ( !Name.getLength() ) + { + throw lang::IllegalArgumentException( OUSTR("Name not set!!"), + Reference < XInterface > (), 1 ); + } + // TODO for Script library pacakge url parse the language, + // for the moment will just try to get each provider to process remove/revoke + // request, the first one the succeeds will terminate processing + + if ( !providerCache() ) + { + throw RuntimeException( + OUSTR("removeByName() cannot instantiate " + "child script providers."), + Reference< XInterface >() ); + } + Sequence < Reference< provider::XScriptProvider > > xSProviders = + providerCache()->getAllProviders(); + sal_Int32 index = 0; + for ( ; index < xSProviders.getLength(); index++ ) + { + Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY ); + if ( !xCont.is() ) + { + continue; + } + try + { + xCont->removeByName( Name ); + break; + } + catch ( Exception& ) + { + } + + } + if ( index == xSProviders.getLength() ) + { + // No script providers could process the package + ::rtl::OUString message = OUSTR("Failed to revoke package for "); + message = message.concat( Name ); + throw lang::IllegalArgumentException( message, + Reference < XInterface > (), 1 ); + } + + } +} + +//************************************************************************* +void SAL_CALL +MasterScriptProvider::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw ( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + (void)aName; + (void)aElement; + + // TODO needs implementing + if ( true ) + { + throw RuntimeException( OUSTR("replaceByName not implemented!!!!") , + Reference< XInterface >() ); + } +} +//************************************************************************* +Any SAL_CALL +MasterScriptProvider::getByName( const ::rtl::OUString& aName ) throw ( container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) +{ + (void)aName; + + // TODO needs to be implemented + Any result; + if ( true ) + { + throw RuntimeException( OUSTR("getByName not implemented!!!!") , + Reference< XInterface >() ); + } + return result; +} +//************************************************************************* +sal_Bool SAL_CALL +MasterScriptProvider::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException) +{ + sal_Bool result = sal_False; + if ( !m_bIsPkgMSP ) + { + if ( m_xMSPPkg.is() ) + { + Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY ); + if ( !xCont.is() ) + { + throw RuntimeException( + OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"), + Reference< XInterface >() ); + } + + result = xCont->hasByName( aName ); + } + else + { + throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"), + Reference< XInterface >() ); + } + + } + else + { + if ( !aName.getLength() ) + { + throw lang::IllegalArgumentException( OUSTR("Name not set!!"), + Reference < XInterface > (), 1 ); + } + // TODO for Script library pacakge url parse the language, + // for the moment will just try to get each provider to see if the + // package exists in any provider, first one that succeed will + // terminate the loop + + if ( !providerCache() ) + { + throw RuntimeException( + OUSTR("removeByName() cannot instantiate " + "child script providers."), + Reference< XInterface >() ); + } + Sequence < Reference< provider::XScriptProvider > > xSProviders = + providerCache()->getAllProviders(); + for ( sal_Int32 index = 0; index < xSProviders.getLength(); index++ ) + { + Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY ); + if ( !xCont.is() ) + { + continue; + } + try + { + result = xCont->hasByName( aName ); + if ( result == sal_True ) + { + break; + } + } + catch ( Exception& ) + { + } + + } + } + return result; +} + +//************************************************************************* +Sequence< ::rtl::OUString > SAL_CALL +MasterScriptProvider::getElementNames( ) throw ( RuntimeException) +{ + // TODO needs implementing + Sequence< ::rtl::OUString > names; + if ( true ) + { + throw RuntimeException( OUSTR("getElementNames not implemented!!!!") , + Reference< XInterface >() ); + } + return names; +} +//************************************************************************* +Type SAL_CALL +MasterScriptProvider::getElementType( ) throw ( RuntimeException) +{ + // TODO needs implementing + Type t; + return t; +} +//************************************************************************* +sal_Bool SAL_CALL MasterScriptProvider::hasElements( ) throw ( RuntimeException) +{ + // TODO needs implementing + if ( true ) + { + throw RuntimeException( OUSTR("hasElements not implemented!!!!") , + Reference< XInterface >() ); + } + return false; +} + +//************************************************************************* +Sequence< Reference< provider::XScriptProvider > > SAL_CALL +MasterScriptProvider::getAllProviders() throw ( css::uno::RuntimeException ) +{ + if ( providerCache() ) + { + return providerCache()->getAllProviders(); + } + else + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( + "MasterScriptProvider::getAllProviders, cache not initialised"); + throw RuntimeException( errorMsg.concat( errorMsg ), + Reference< XInterface >() ); + } +} + + +//************************************************************************* +::rtl::OUString SAL_CALL MasterScriptProvider::getImplementationName( ) +throw( RuntimeException ) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.MasterScriptProvider" ) ); +} + +//************************************************************************* +sal_Bool SAL_CALL MasterScriptProvider::supportsService( const ::rtl::OUString& serviceName ) +throw( RuntimeException ) +{ + Sequence< ::rtl::OUString > serviceNames( getSupportedServiceNames() ); + ::rtl::OUString const * pNames = serviceNames.getConstArray(); + for ( sal_Int32 nPos = serviceNames.getLength(); nPos--; ) + { + if ( serviceName.equals( pNames[ nPos ] ) ) + { + return sal_True; + } + } + return sal_False; +} + +//************************************************************************* +Sequence< ::rtl::OUString > SAL_CALL MasterScriptProvider::getSupportedServiceNames( ) +throw( RuntimeException ) +{ + ::rtl::OUString names[3]; + + names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.MasterScriptProvider" ) ); + names[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.browse.BrowseNode" ) ); + names[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.ScriptProvider" ) ); + + return Sequence< ::rtl::OUString >( names, 3 ); +} + +} // namespace func_provider + + +namespace browsenodefactory +{ +::rtl::OUString SAL_CALL bnf_getImplementationName() ; +Reference< XInterface > SAL_CALL bnf_create( Reference< XComponentContext > const & xComponentContext ); +Sequence< ::rtl::OUString > SAL_CALL bnf_getSupportedServiceNames(); +} + +namespace scripting_runtimemgr +{ +//************************************************************************* +Reference< XInterface > SAL_CALL sp_create( + const Reference< XComponentContext > & xCompC ) +{ + return ( cppu::OWeakObject * ) new ::func_provider::MasterScriptProvider( xCompC ); +} + +//************************************************************************* +Sequence< ::rtl::OUString > sp_getSupportedServiceNames( ) + SAL_THROW( () ) +{ + ::rtl::OUString names[3]; + + names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.MasterScriptProvider" ) ); + names[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.browse.BrowseNode" ) ); + names[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.ScriptProvider" ) ); + + return Sequence< ::rtl::OUString >( names, 3 ); +} + +//************************************************************************* +::rtl::OUString sp_getImplementationName( ) +SAL_THROW( () ) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.MasterScriptProvider" ) ); +} + +// ***** registration or ScriptingFrameworkURIHelper +Reference< XInterface > SAL_CALL urihelper_create( + const Reference< XComponentContext > & xCompC ) +{ + return ( cppu::OWeakObject * ) + new ::func_provider::ScriptingFrameworkURIHelper( xCompC ); +} + +Sequence< ::rtl::OUString > urihelper_getSupportedServiceNames( ) + SAL_THROW( () ) +{ + ::rtl::OUString serviceNameList[] = { + ::rtl::OUString::createFromAscii( + "com.sun.star.script.provider.ScriptURIHelper" ) }; + + Sequence< ::rtl::OUString > serviceNames = Sequence < + ::rtl::OUString > ( serviceNameList, 1 ); + + return serviceNames; +} + +::rtl::OUString urihelper_getImplementationName( ) + SAL_THROW( () ) +{ + return ::rtl::OUString::createFromAscii( + "com.sun.star.script.provider.ScriptURIHelper"); +} + +static struct cppu::ImplementationEntry s_entries [] = + { + { + sp_create, sp_getImplementationName, + sp_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { + urihelper_create, + urihelper_getImplementationName, + urihelper_getSupportedServiceNames, + cppu::createSingleComponentFactory, + 0, 0 + }, + { + func_provider::mspf_create, func_provider::mspf_getImplementationName, + func_provider::mspf_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { + browsenodefactory::bnf_create, browsenodefactory::bnf_getImplementationName, + browsenodefactory::bnf_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; +} + +//############################################################################ +//#### EXPORTED ############################################################## +//############################################################################ + +/** + * Gives the environment this component belongs to. + */ +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) + { + (void)ppEnv; + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + /** + * This function creates an implementation section in the registry and another subkey + * + * for each supported service. + * @param pServiceManager the service manager + * @param pRegistryKey the registry key + */ + SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + if (::cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, + ::scripting_runtimemgr::s_entries )) + { + try + { + // MasterScriptProviderFactory Mangager singleton + registry::XRegistryKey * pKey = + reinterpret_cast< registry::XRegistryKey * >(pRegistryKey); + + Reference< registry::XRegistryKey >xKey = pKey->createKey( + OUSTR("com.sun.star.script.provider.MasterScriptProviderFactory/UNO/SINGLETONS/com.sun.star.script.provider.theMasterScriptProviderFactory")); + xKey->setStringValue( OUSTR("com.sun.star.script.provider.MasterScriptProviderFactory") ); + // BrowseNodeFactory Mangager singleton + xKey = pKey->createKey( + OUSTR("com.sun.star.script.browse.BrowseNodeFactory/UNO/SINGLETONS/com.sun.star.script.browse.theBrowseNodeFactory")); + xKey->setStringValue( OUSTR("com.sun.star.script.browse.BrowseNodeFactory") ); + return sal_True; + } + catch (Exception &) + { + } + } + return sal_False; + } + + /** + * This function is called to get service factories for an implementation. + * + * @param pImplName name of implementation + * @param pServiceManager a service manager, need for component creation + * @param pRegistryKey the registry key for this component, need for persistent + * data + * @return a component factory + */ + SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, + lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, + pRegistryKey, ::scripting_runtimemgr::s_entries ); + } +} diff --git a/scripting/source/provider/MasterScriptProvider.hxx b/scripting/source/provider/MasterScriptProvider.hxx new file mode 100644 index 000000000000..76deec00ab8f --- /dev/null +++ b/scripting/source/provider/MasterScriptProvider.hxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_PROVIDER_XFUNCTIONPROVIDER_HXX_ +#define _FRAMEWORK_SCRIPT_PROVIDER_XFUNCTIONPROVIDER_HXX_ + +#include <rtl/ustring.hxx> + +#include <cppuhelper/implbase5.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> + +#include <com/sun/star/lang/XInitialization.hpp> + +#include <com/sun/star/script/provider/XScriptProvider.hpp> +#include <com/sun/star/script/browse/XBrowseNode.hpp> + +#include "ProviderCache.hxx" + +namespace func_provider +{ +// for simplification +#define css ::com::sun::star + + typedef ::cppu::WeakImplHelper5< + css::script::provider::XScriptProvider, + css::script::browse::XBrowseNode, css::lang::XServiceInfo, + css::lang::XInitialization, + css::container::XNameContainer > t_helper; + +class MasterScriptProvider : + public t_helper +{ +public: + MasterScriptProvider( + const css::uno::Reference< css::uno::XComponentContext > + & xContext ) throw( css::uno::RuntimeException ); + ~MasterScriptProvider(); + + // XServiceInfo implementation + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw( css::uno::RuntimeException ); + + // XBrowseNode implementation + virtual ::rtl::OUString SAL_CALL getName() + throw ( css::uno::RuntimeException ); + virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes() + throw ( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL hasChildNodes() + throw ( css::uno::RuntimeException ); + virtual sal_Int16 SAL_CALL getType() + throw ( css::uno::RuntimeException ); + // XNameContainer + virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const css::uno::Any& aElement ) throw ( css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, css::uno::RuntimeException); + virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw ( css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException); + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const css::uno::Any& aElement ) throw ( css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException); + // XNameAccess + virtual css::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw ( css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw ( css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) throw ( css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements( ) throw ( css::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw( css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw( css::uno::RuntimeException ); + + // XScriptProvider implementation + virtual css::uno::Reference < css::script::provider::XScript > SAL_CALL + getScript( const ::rtl::OUString& scriptURI ) + throw( css::script::provider::ScriptFrameworkErrorException, + css::uno::RuntimeException ); + + /** + * XInitialise implementation + * + * @param args expected to contain a single ::rtl::OUString + * containing the URI + */ + virtual void SAL_CALL initialize( const css::uno::Sequence < css::uno::Any > & args ) + throw ( css::uno::Exception, css::uno::RuntimeException); + + // Public method to return all Language Providers in this MasterScriptProviders + // context. + css::uno::Sequence< css::uno::Reference< css::script::provider::XScriptProvider > > SAL_CALL + getAllProviders() throw ( css::uno::RuntimeException ); + + bool isPkgProvider() { return m_bIsPkgMSP; } + css::uno::Reference< css::script::provider::XScriptProvider > getPkgProvider() { return m_xMSPPkg; } + // returns context string for this provider, eg + ::rtl::OUString getContextString() { return m_sCtxString; } + +private: + ::rtl::OUString parseLocationName( const ::rtl::OUString& location ); + void createPkgProvider(); + bool isValid(); + ::rtl::OUString getURLForModel(); + const css::uno::Sequence< ::rtl::OUString >& getProviderNames(); + + ProviderCache* providerCache(); + /* to obtain other services if needed */ + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMgr; + css::uno::Reference< css::frame::XModel > m_xModel; + css::uno::Reference< css::document::XScriptInvocationContext > m_xInvocationContext; + css::uno::Sequence< css::uno::Any > m_sAargs; + ::rtl::OUString m_sNodeName; + + // This component supports XInitialization, it can be created + // using createInstanceXXX() or createInstanceWithArgumentsXXX using + // the service Mangager. + // Need to detect proper initialisation and validity + // for the object, so m_bIsValid indicates that the object is valid is set in ctor + // in case of createInstanceWithArgumentsXXX() called m_bIsValid is set to reset + // and then set to true when initialisation is complete + bool m_bIsValid; + // m_bInitialised ensure initialisation only takes place once. + bool m_bInitialised; + bool m_bIsPkgMSP; + css::uno::Reference< css::script::provider::XScriptProvider > m_xMSPPkg; + ProviderCache* m_pPCache; + osl::Mutex m_mutex; + ::rtl::OUString m_sCtxString; +}; +} // namespace func_provider +#endif //_FRAMEWORK_SCRIPT_PROVIDER_XFUNCTIONPROVIDER_HXX_ diff --git a/scripting/source/provider/MasterScriptProviderFactory.cxx b/scripting/source/provider/MasterScriptProviderFactory.cxx new file mode 100644 index 000000000000..cd1aa83da3c7 --- /dev/null +++ b/scripting/source/provider/MasterScriptProviderFactory.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <cppuhelper/weakref.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <util/util.hxx> + +#include "MasterScriptProviderFactory.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script; + +namespace func_provider +{ + +MasterScriptProviderFactory::MasterScriptProviderFactory( + Reference< XComponentContext > const & xComponentContext ) + : m_xComponentContext( xComponentContext ) +{ +} + +MasterScriptProviderFactory::~MasterScriptProviderFactory() +{ +} + + +//############################################################################ +// Implementation of XScriptProviderFactory +//############################################################################ + + +Reference< provider::XScriptProvider > SAL_CALL +MasterScriptProviderFactory::createScriptProvider( const Any& context ) throw ( lang::IllegalArgumentException, RuntimeException) +{ + Reference< provider::XScriptProvider > xMsp( getActiveMSPList() ->getMSPFromAnyContext( context ), UNO_QUERY_THROW ); + return xMsp; +} + +//############################################################################ +// Helper methods +//############################################################################ + +const rtl::Reference< ActiveMSPList > & +MasterScriptProviderFactory::getActiveMSPList() const +{ + if ( !m_MSPList.is() ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if ( !m_MSPList.is() ) + m_MSPList = new ActiveMSPList( m_xComponentContext ); + } + return m_MSPList; +} + +//############################################################################ +// Namespace global methods for setting up MasterScriptProviderFactory service +//############################################################################ + +Sequence< ::rtl::OUString > SAL_CALL +mspf_getSupportedServiceNames( ) + SAL_THROW( () ) +{ + ::rtl::OUString str_name = ::rtl::OUString::createFromAscii( + "com.sun.star.script.provider.MasterScriptProviderFactory"); + + return Sequence< ::rtl::OUString >( &str_name, 1 ); +} + +::rtl::OUString SAL_CALL +mspf_getImplementationName( ) + SAL_THROW( () ) +{ + return ::rtl::OUString::createFromAscii( + "com.sun.star.script.provider.MasterScriptProviderFactory"); +} + +Reference< XInterface > SAL_CALL +mspf_create( Reference< XComponentContext > const & xComponentContext ) + SAL_THROW( (Exception) ) +{ + return static_cast< ::cppu::OWeakObject * >( + new MasterScriptProviderFactory( xComponentContext ) ); +} + +//############################################################################ +// Implementation of XServiceInfo +//############################################################################ + +::rtl::OUString SAL_CALL +MasterScriptProviderFactory::getImplementationName() + throw (RuntimeException) +{ + return mspf_getImplementationName(); +} + +Sequence< ::rtl::OUString > SAL_CALL +MasterScriptProviderFactory::getSupportedServiceNames() + throw (RuntimeException) +{ + return mspf_getSupportedServiceNames(); +} + +sal_Bool MasterScriptProviderFactory::supportsService( + ::rtl::OUString const & serviceName ) + throw (RuntimeException) +{ +// check(); + + Sequence< ::rtl::OUString > supported_services( + getSupportedServiceNames() ); + + ::rtl::OUString const * ar = supported_services.getConstArray(); + + for ( sal_Int32 pos = supported_services.getLength(); pos--; ) + { + if (ar[ pos ].equals( serviceName )) + return true; + } + return false; +} + +} // namespace browsenodefactory diff --git a/scripting/source/provider/MasterScriptProviderFactory.hxx b/scripting/source/provider/MasterScriptProviderFactory.hxx new file mode 100644 index 000000000000..16018bf13a54 --- /dev/null +++ b/scripting/source/provider/MasterScriptProviderFactory.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "rtl/ustring.hxx" +#include "rtl/ref.hxx" +#include <cppuhelper/implbase2.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include <com/sun/star/script/provider/XScriptProviderFactory.hpp> +#include <com/sun/star/script/provider/XScriptProvider.hpp> + +#include "ActiveMSPList.hxx" + +namespace func_provider +{ +// for simplification +#define css ::com::sun::star + +class MasterScriptProviderFactory : + public ::cppu::WeakImplHelper2 < + css::script::provider::XScriptProviderFactory, + css::lang::XServiceInfo > +{ +private: + + mutable rtl::Reference< ActiveMSPList > m_MSPList; + + const css::uno::Reference< css::uno::XComponentContext > m_xComponentContext; + + const rtl::Reference< ActiveMSPList > & getActiveMSPList() const; + +protected: + virtual ~MasterScriptProviderFactory(); + +public: + MasterScriptProviderFactory( + css::uno::Reference< css::uno::XComponentContext > const & xComponentContext ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw ( css::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( ::rtl::OUString const & serviceName ) + throw ( css::uno::RuntimeException ); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw ( css::uno::RuntimeException ); + + // XScriptProviderFactory + virtual css::uno::Reference< css::script::provider::XScriptProvider > + SAL_CALL createScriptProvider( const css::uno::Any& context ) + throw ( css::lang::IllegalArgumentException, css::uno::RuntimeException); +}; + + +} // namespace func_provider diff --git a/scripting/source/provider/ProviderCache.cxx b/scripting/source/provider/ProviderCache.cxx new file mode 100644 index 000000000000..5d3350f635e3 --- /dev/null +++ b/scripting/source/provider/ProviderCache.cxx @@ -0,0 +1,222 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/factory.hxx> + +#include <util/scriptingconstants.hxx> +#include <util/util.hxx> + +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include "ProviderCache.hxx" + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::script; +using namespace ::scripting_util; + +namespace func_provider +{ + +ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext ) + throw ( RuntimeException ) : m_Sctx( scriptContext ), m_xContext( xContext ) +{ + // initialise m_hProviderDetailsCache with details of ScriptProviders + // will use createContentEnumeration + + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); + populateCache(); +} + + +ProviderCache::ProviderCache( const Reference< XComponentContext >& xContext, const Sequence< Any >& scriptContext, const Sequence< ::rtl::OUString >& blackList ) + throw ( RuntimeException ) : m_sBlackList( blackList ), m_Sctx( scriptContext ), m_xContext( xContext ) + +{ + // initialise m_hProviderDetailsCache with details of ScriptProviders + // will use createContentEnumeration + + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, "ProviderCache::ProviderCache() failed to obtain ServiceManager" ); + populateCache(); +} + +ProviderCache::~ProviderCache() +{ +} + +Reference< provider::XScriptProvider > +ProviderCache::getProvider( const ::rtl::OUString& providerName ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + Reference< provider::XScriptProvider > provider; + ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.find( providerName ); + if ( h_it != m_hProviderDetailsCache.end() ) + { + if ( h_it->second.provider.is() ) + { + provider = h_it->second.provider; + } + else + { + // need to create provider and insert into hash + provider = createProvider( h_it->second ); + } + } + return provider; +} + +Sequence < Reference< provider::XScriptProvider > > +ProviderCache::getAllProviders() throw ( RuntimeException ) +{ + Sequence < Reference< provider::XScriptProvider > > providers ( m_hProviderDetailsCache.size() ); + // need to create providers that haven't been created already + // so check what providers exist and what ones don't + + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + ProviderDetails_hash::iterator h_itEnd = m_hProviderDetailsCache.end(); + ProviderDetails_hash::iterator h_it = m_hProviderDetailsCache.begin(); + // should assert if size !> 0 + if ( m_hProviderDetailsCache.size() ) + { + sal_Int32 providerIndex = 0; + sal_Int32 index = 0; + for ( index = 0; h_it != h_itEnd; ++h_it, index++ ) + { + Reference< provider::XScriptProvider > xScriptProvider = h_it->second.provider; + if ( xScriptProvider.is() ) + { + providers[ providerIndex++ ] = xScriptProvider; + } + else + { + // create provider + try + { + xScriptProvider = createProvider( h_it->second ); + providers[ providerIndex++ ] = xScriptProvider; + } + catch ( Exception& e ) + { + ::rtl::OUString temp = OUSTR( "ProviderCache::getAllProviders: failed to create provider, " ); + temp.concat( e.Message ); + //throw RuntimeException( temp.concat( e.Message ), + // Reference< XInterface >() ); + } + } + } + + if ( providerIndex < index ) + { + providers.realloc( providerIndex ); + } + + } + else + { + OSL_TRACE("no available providers, something very wrong!!!"); + } + return providers; +} + +void +ProviderCache::populateCache() throw ( RuntimeException ) +{ + // wrong name in services.rdb + ::rtl::OUString serviceName; + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + try + { + ::rtl::OUString languageProviderName( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.script.provider.LanguageScriptProvider" ) ); + + Reference< container::XContentEnumerationAccess > xEnumAccess = Reference< container::XContentEnumerationAccess >( m_xMgr, UNO_QUERY_THROW ); + Reference< container::XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName ); + + while ( xEnum->hasMoreElements() ) + { + + Reference< lang::XSingleComponentFactory > factory; + if ( sal_False == ( xEnum->nextElement() >>= factory ) ) + { + throw new RuntimeException( ::rtl::OUString::createFromAscii( " error extracting XSingleComponentFactory from Content enumeration. " ), Reference< XInterface >() ); + } + validateXRef( factory, "ProviderCache::populateCache() invalid factory" ); + Reference< lang::XServiceInfo > xServiceInfo( factory, UNO_QUERY_THROW ); + validateXRef( xServiceInfo, "ProviderCache::populateCache() failed to get XServiceInfo from factory" ); + + Sequence< ::rtl::OUString > serviceNames = xServiceInfo->getSupportedServiceNames(); + + if ( serviceNames.getLength() > 0 ) + { + ::rtl::OUString searchString( RTL_CONSTASCII_USTRINGPARAM ( + "com.sun.star.script.provider.ScriptProviderFor" ) ); + + for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ ) + { + if ( serviceNames[ index ].indexOf( searchString ) == 0 && !isInBlackList( serviceNames[ index ] ) ) + { + serviceName = serviceNames[ index ]; + ProviderDetails details; + details.factory = factory; + m_hProviderDetailsCache[ serviceName ] = details; + break; + } + } + } + } + } + catch ( Exception e ) + { + ::rtl::OUString temp = OUSTR( + "ProviderCache::populateCache: couldn't obtain XSingleComponentFactory for " ); + temp.concat( serviceName ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } +} + +Reference< provider::XScriptProvider > +ProviderCache::createProvider( ProviderDetails& details ) throw ( RuntimeException ) +{ + try + { + details.provider = Reference< provider::XScriptProvider >( + details.factory->createInstanceWithArgumentsAndContext( m_Sctx, m_xContext ), UNO_QUERY_THROW ); + validateXRef( details.provider, "ProviderCache::createProvider, failed to create provider"); + } + catch ( RuntimeException& e ) + { + ::rtl::OUString temp = ::rtl::OUString::createFromAscii("ProviderCache::createProvider() Error creating provider from factory!!!"); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + + return details.provider; +} +} //end namespace diff --git a/scripting/source/provider/ProviderCache.hxx b/scripting/source/provider/ProviderCache.hxx new file mode 100644 index 000000000000..f747c067ac3d --- /dev/null +++ b/scripting/source/provider/ProviderCache.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_PROVIDER_PROVIDERCACHE_HXX_ +#define _FRAMEWORK_SCRIPT_PROVIDER_PROVIDERCACHE_HXX_ + +#include <hash_map> +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/script/provider/XScriptProvider.hpp> + +#include "ScriptingContext.hxx" + +namespace func_provider +{ +// for simplification +#define css ::com::sun::star + +//Typedefs +//============================================================================= + +struct ProviderDetails +{ + //css::uno::Reference< css::lang::XSingleServiceFactory > factory; + css::uno::Reference< css::lang::XSingleComponentFactory > factory; + css::uno::Reference< css::script::provider::XScriptProvider > provider; +}; +typedef ::std::hash_map < ::rtl::OUString, ProviderDetails , ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > ProviderDetails_hash; + + +class ProviderCache +{ + +public: + ProviderCache( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Sequence< css::uno::Any >& scriptContext ) + throw ( css::uno::RuntimeException ); + ProviderCache( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Sequence< css::uno::Any >& scriptContext, + const css::uno::Sequence< ::rtl::OUString >& blackList ) + throw ( css::uno::RuntimeException ); + ~ProviderCache(); + css::uno::Reference< css::script::provider::XScriptProvider > + getProvider( const ::rtl::OUString& providerName ); + css::uno::Sequence < css::uno::Reference< css::script::provider::XScriptProvider > > + getAllProviders() throw ( css::uno::RuntimeException ); +private: + void populateCache() + throw ( css::uno::RuntimeException ); + + css::uno::Reference< css::script::provider::XScriptProvider > + createProvider( ProviderDetails& details ) throw ( css::uno::RuntimeException ); + bool isInBlackList( const ::rtl::OUString& serviceName ) + { + if ( m_sBlackList.getLength() > 0 ) + { + for ( sal_Int32 index = 0; index < m_sBlackList.getLength(); index++ ) + { + if ( m_sBlackList[ index ].equals( serviceName ) ) + { + return true; + } + } + } + return false; + } + css::uno::Sequence< ::rtl::OUString > m_sBlackList; + ProviderDetails_hash m_hProviderDetailsCache; + osl::Mutex m_mutex; + css::uno::Sequence< css::uno::Any > m_Sctx; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMgr; + + +}; +} // func_provider +#endif diff --git a/scripting/source/provider/ScriptImpl.cxx b/scripting/source/provider/ScriptImpl.cxx new file mode 100644 index 000000000000..f5b93a802138 --- /dev/null +++ b/scripting/source/provider/ScriptImpl.cxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <stdio.h> + +#include "ScriptImpl.hxx" +#include <util/util.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::script::framework; + +namespace func_provider +{ + +//************************************************************************* +ScriptImpl::ScriptImpl( + const Reference< beans::XPropertySet > & scriptingContext, + const Reference< runtime::XScriptInvocation > & runtimeMgr, + const ::rtl::OUString& scriptURI ) +throw ( RuntimeException ) : + m_XScriptingContext( scriptingContext ), + m_RunTimeManager( runtimeMgr ), + m_ScriptURI( scriptURI ) +{ + OSL_TRACE( "<!constucting a ScriptImpl>\n" ); + validateXRef( m_XScriptingContext, + "ScriptImpl::ScriptImpl: No XScriptingContext\n" ); + validateXRef( m_RunTimeManager, + "ScriptImpl::ScriptImpl: No XScriptInvocation\n" ); +} + +//************************************************************************* +ScriptImpl::~ScriptImpl() +{ + OSL_TRACE( "<Destructing a ScriptImpl>\n" ); +} + +//************************************************************************* +Any SAL_CALL +ScriptImpl::invoke( const Sequence< Any >& aParams, + Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) +throw ( lang::IllegalArgumentException, script::CannotConvertException, + reflection::InvocationTargetException, RuntimeException ) +{ + OSL_TRACE( "<ScriptImpl::invoke>" ); + Any result; + Any anyScriptingContext; + + anyScriptingContext <<= m_XScriptingContext; + try + { + result = m_RunTimeManager->invoke( m_ScriptURI, anyScriptingContext, aParams, + aOutParamIndex, aOutParam ); + } + catch ( lang::IllegalArgumentException & iae ) + { + ::rtl::OUString temp = OUSTR( "ScriptImpl::invoke IllegalArgumentException : " ); + throw lang::IllegalArgumentException( temp.concat( iae.Message ), + Reference< XInterface > (), + iae.ArgumentPosition ); + } + catch ( script::CannotConvertException & cce ) + { + ::rtl::OUString temp = OUSTR( "ScriptImpl::invoke CannotConvertException : " ); + throw script::CannotConvertException( temp.concat( cce.Message ), + Reference< XInterface > (), + cce.DestinationTypeClass, + cce.Reason, + cce.ArgumentIndex ); + } + catch ( reflection::InvocationTargetException & ite ) + { + ::rtl::OUString temp = OUSTR( "ScriptImpl::invoke InvocationTargetException : " ); + throw reflection::InvocationTargetException( temp.concat( ite.Message ), + Reference< XInterface > (), + ite.TargetException ); + } + catch ( RuntimeException & re ) + { + ::rtl::OUString temp = OUSTR( "ScriptImpl::invoke RuntimeException : " ); + throw RuntimeException( temp.concat( re.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( + OUSTR( "ScriptImpl::invoke Unknown Exception caught - RuntimeException rethrown" ), + Reference< XInterface > () ); + } +#endif + return result; +} +} // namespace func_provider diff --git a/scripting/source/provider/ScriptImpl.hxx b/scripting/source/provider/ScriptImpl.hxx new file mode 100644 index 000000000000..fddaf11a35df --- /dev/null +++ b/scripting/source/provider/ScriptImpl.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_PROVIDER_FUNCTIONIMPL_HXX_ +#define _FRAMEWORK_SCRIPT_PROVIDER_FUNCTIONIMPL_HXX_ + +#include <cppuhelper/implbase1.hxx> // helper for XInterface, XTypeProvider etc. +#include <osl/mutex.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/script/CannotConvertException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/reflection/InvocationTargetException.hpp> + +#include <drafts/com/sun/star/script/framework/provider/XScript.hpp> +#include <drafts/com/sun/star/script/framework/runtime/XScriptInvocation.hpp> + +namespace func_provider +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + + +class ScriptImpl : + public ::cppu::WeakImplHelper1 < dcsssf::provider::XScript > +{ + +public: + /************************************************************* + ScriptImpl Constructor + @param runtimeMgr which is a service that implement a XScriptInvocation + @param scriptURI the received ScriptURI that needs to be resolve and invoked + */ + ScriptImpl( + const css::uno::Reference< css::beans::XPropertySet > & scriptingContext, + const css::uno::Reference< dcsssf::runtime::XScriptInvocation > & runtimeMgr, + const ::rtl::OUString& scriptURI ) + throw ( css::uno::RuntimeException ); + + /************************************************************* + ScriptImpl Destructor + */ + ~ScriptImpl(); + + /************************************************************* + Invoke + @param aParams all parameters; pure, out params are undefined in sequence, + i.e., the value has to be ignored by the callee + @param aOutParamIndex out indices + @param aOutParam out parameters + + @returns + the value returned from the function being invoked + + @throws IllegalArgumentException + if there is no matching script name + + @throws CannotConvertException + if args do not match or cannot be converted the those + of the invokee + + @throws InvocationTargetException + if the running script throws an exception this information is captured and + rethrown as this exception type. + + */ + virtual css::uno::Any SAL_CALL invoke( + const css::uno::Sequence< css::uno::Any > & aParams, + css::uno::Sequence< sal_Int16 > & aOutParamIndex, + css::uno::Sequence< css::uno::Any > & aOutParam ) + throw ( css::lang::IllegalArgumentException, + css::script::CannotConvertException, + css::reflection::InvocationTargetException, + css::uno::RuntimeException ); + +private: + css::uno::Reference< css::beans::XPropertySet > m_XScriptingContext; + css::uno::Reference < dcsssf::runtime::XScriptInvocation > m_RunTimeManager; + ::rtl::OUString m_ScriptURI; + + /* copy ctor disabled, i.e. not defined */ + ScriptImpl( const ScriptImpl& ); + /* assignment disabled, i.e. not defined */ + ScriptImpl& operator = ( const ScriptImpl& ); +}; +} // namespace func_provider +#endif //_FRAMEWORK_SCRIPT_PROVIDER_FUNCTIONIMPL_HXX_ diff --git a/scripting/source/provider/ScriptingContext.cxx b/scripting/source/provider/ScriptingContext.cxx new file mode 100755 index 000000000000..08a27a19562f --- /dev/null +++ b/scripting/source/provider/ScriptingContext.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/frame/XModel.hpp> + +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/factory.hxx> + +#include <util/scriptingconstants.hxx> +#include <util/util.hxx> + +#include "ScriptingContext.hxx" + +using namespace com::sun::star; +using namespace com::sun::star::uno; +#define DOC_REF_PROPID 1 +#define DOC_STORAGE_ID_PROPID 2 +#define DOC_URI_PROPID 3 +#define RESOLVED_STORAGE_ID_PROPID 4 +#define SCRIPT_INFO_PROPID 5 +#define SCRIPTINGCONTEXT_DEFAULT_ATTRIBS() beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::MAYBEVOID +namespace func_provider +{ + +//************************************************************************* +// XScriptingContext implementation +// +//************************************************************************* +ScriptingContext::ScriptingContext( const Reference< XComponentContext > & xContext ) : //ScriptingContextImpl_BASE( GetMutex()), + OPropertyContainer( GetBroadcastHelper() ), + m_xContext( xContext ) +{ + OSL_TRACE( "< ScriptingContext ctor called >\n" ); + + validateXRef( m_xContext, + "ScriptingContext::ScriptingContext: No context available\n" ); + + Any nullAny; + + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + registerPropertyNoMember( scriptingConstantsPool.DOC_REF, DOC_REF_PROPID, SCRIPTINGCONTEXT_DEFAULT_ATTRIBS(),::getCppuType( (const Reference< css::frame::XModel >* ) NULL ), NULL ) ; + registerPropertyNoMember( scriptingConstantsPool.DOC_STORAGE_ID, DOC_STORAGE_ID_PROPID, SCRIPTINGCONTEXT_DEFAULT_ATTRIBS(), ::getCppuType( (const sal_Int32* ) NULL ), NULL ) ; + registerPropertyNoMember( scriptingConstantsPool.DOC_URI, DOC_URI_PROPID, SCRIPTINGCONTEXT_DEFAULT_ATTRIBS(), ::getCppuType( (const ::rtl::OUString* ) NULL ), NULL ) ; + registerPropertyNoMember( scriptingConstantsPool.RESOLVED_STORAGE_ID, RESOLVED_STORAGE_ID_PROPID, SCRIPTINGCONTEXT_DEFAULT_ATTRIBS(), ::getCppuType( (const sal_Int32* ) NULL ), NULL ); + registerPropertyNoMember( scriptingConstantsPool.SCRIPT_INFO, SCRIPT_INFO_PROPID, SCRIPTINGCONTEXT_DEFAULT_ATTRIBS(), ::getCppuType( (const sal_Int32* ) NULL ), NULL ); +} + +ScriptingContext::~ScriptingContext() +{ + OSL_TRACE( "< ScriptingContext dtor called >\n" ); +} +// ----------------------------------------------------------------------------- +// OPropertySetHelper +// ----------------------------------------------------------------------------- + +::cppu::IPropertyArrayHelper& ScriptingContext::getInfoHelper( ) +{ + return *getArrayHelper(); +} + +// ----------------------------------------------------------------------------- +// OPropertyArrayUsageHelper +// ----------------------------------------------------------------------------- + +::cppu::IPropertyArrayHelper* ScriptingContext::createArrayHelper( ) const +{ + Sequence< beans::Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); +} +// ----------------------------------------------------------------------------- +// XPropertySet +// ----------------------------------------------------------------------------- + +Reference< beans::XPropertySetInfo > ScriptingContext::getPropertySetInfo( ) throw (RuntimeException) +{ + Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} +// -----------------------------------------------------------------------------// XTypeProvider +// ----------------------------------------------------------------------------- +IMPLEMENT_GET_IMPLEMENTATION_ID( ScriptingContext ) + +css::uno::Sequence< css::uno::Type > SAL_CALL ScriptingContext::getTypes( ) throw (css::uno::RuntimeException) +{ + return OPropertyContainer::getTypes(); +} +} // namespace func_provider diff --git a/scripting/source/provider/ScriptingContext.hxx b/scripting/source/provider/ScriptingContext.hxx new file mode 100644 index 000000000000..8c0b25814142 --- /dev/null +++ b/scripting/source/provider/ScriptingContext.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_PROTOCOLHANDLER_SCRIPTING_CONTEXT_HXX_ +#define _FRAMEWORK_SCRIPT_PROTOCOLHANDLER_SCRIPTING_CONTEXT_HXX_ + + +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase1.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/propertycontainer.hxx> +#include <comphelper/proparrhlp.hxx> + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <comphelper/broadcasthelper.hxx> +namespace func_provider +{ +// for simplification +#define css ::com::sun::star + +//Typedefs +//============================================================================= +//typedef ::cppu::WeakImplHelper1< css::beans::XPropertySet > ScriptingContextImpl_BASE; + +class ScriptingContext : public ::comphelper::OMutexAndBroadcastHelper, public ::comphelper::OPropertyContainer, + public ::comphelper::OPropertyArrayUsageHelper< ScriptingContext >, public css::lang::XTypeProvider, public ::cppu::OWeakObject +{ + +public: + ScriptingContext( const css::uno::Reference< css::uno::XComponentContext > & xContext ); + ~ScriptingContext(); + // XInterface + + css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType ) + throw( css::uno::RuntimeException ) + { + css::uno::Any aRet( OPropertySetHelper::queryInterface( rType ) ); + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); + } + void SAL_CALL acquire() throw() { ::cppu::OWeakObject::acquire(); } + void SAL_CALL release() throw() { ::cppu::OWeakObject::release(); } + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) + throw ( css::uno::RuntimeException ); + //XTypeProvider + DECLARE_XTYPEPROVIDER( ) + +protected: + + // OPropertySetHelper + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( ); + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; +private: + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + +}; +} // func_provider +#endif //_FRAMEWORK_SCRIPT_PROVIDER_XFUNCTIONPROVIDER_HXX_ diff --git a/scripting/source/provider/URIHelper.cxx b/scripting/source/provider/URIHelper.cxx new file mode 100644 index 000000000000..d6d8e9d01337 --- /dev/null +++ b/scripting/source/provider/URIHelper.cxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> +#include <rtl/ustrbuf.hxx> +#include "URIHelper.hxx" + +#define PRTSTR(x) ::rtl::OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer + +namespace func_provider +{ + +using ::rtl::OUString; +namespace uno = ::com::sun::star::uno; +namespace ucb = ::com::sun::star::ucb; +namespace lang = ::com::sun::star::lang; +namespace uri = ::com::sun::star::uri; +namespace script = ::com::sun::star::script; + +static const char SHARE[] = "share"; +static const char SHARE_URI[] = + "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::BaseInstallation}"; + +static const char SHARE_UNO_PACKAGES[] = "share:uno_packages"; +static const char SHARE_UNO_PACKAGES_URI[] = + "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE"; + +static const char USER[] = "user"; +static const char USER_URI[] = + "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}"; + +static const char USER_UNO_PACKAGES[] = "user:uno_packages"; +static const char USER_UNO_PACKAGES_DIR[] = + "/user/uno_packages/cache"; + +static const char DOCUMENT[] = "document"; +static const char TDOC_SCHEME[] = "vnd.sun.star.tdoc"; + +ScriptingFrameworkURIHelper::ScriptingFrameworkURIHelper( + const uno::Reference< uno::XComponentContext >& xContext) + throw( uno::RuntimeException ) +{ + try + { + m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >( + xContext->getServiceManager()->createInstanceWithContext( + OUString::createFromAscii( + "com.sun.star.ucb.SimpleFileAccess"), + xContext), uno::UNO_QUERY_THROW); + } + catch (uno::Exception&) + { + OSL_ENSURE(false, + "Scripting Framework error initialising XSimpleFileAccess"); + } + + try + { + m_xUriReferenceFactory = uno::Reference< uri::XUriReferenceFactory >( + xContext->getServiceManager()->createInstanceWithContext( + OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), + xContext ), uno::UNO_QUERY_THROW ); + } + catch (uno::Exception&) + { + OSL_ENSURE(false, + "Scripting Framework error initialising XUriReferenceFactory"); + } +} + +ScriptingFrameworkURIHelper::~ScriptingFrameworkURIHelper() +{ + // currently does nothing +} + +void SAL_CALL +ScriptingFrameworkURIHelper::initialize( + const uno::Sequence < uno::Any >& args ) +throw ( uno::Exception, uno::RuntimeException ) +{ + if ( args.getLength() != 2 || + args[0].getValueType() != ::getCppuType((const OUString*)NULL) || + args[1].getValueType() != ::getCppuType((const OUString*)NULL) ) + { + throw uno::RuntimeException( OUString::createFromAscii( + "ScriptingFrameworkURIHelper got invalid argument list" ), + uno::Reference< uno::XInterface >() ); + } + + if ( (args[0] >>= m_sLanguage) == sal_False || + (args[1] >>= m_sLocation) == sal_False ) + { + throw uno::RuntimeException( OUString::createFromAscii( + "ScriptingFrameworkURIHelper error parsing args" ), + uno::Reference< uno::XInterface >() ); + } + + SCRIPTS_PART = OUString::createFromAscii( "/Scripts/" ); + SCRIPTS_PART = SCRIPTS_PART.concat( m_sLanguage.toAsciiLowerCase() ); + + if ( !initBaseURI() ) + { + throw uno::RuntimeException( OUString::createFromAscii( + "ScriptingFrameworkURIHelper cannot find script directory"), + uno::Reference< uno::XInterface >() ); + } +} + +bool +ScriptingFrameworkURIHelper::initBaseURI() +{ + OUString uri, test; + bool bAppendScriptsPart = false; + + if ( m_sLocation.equalsAscii(USER)) + { + test = OUString::createFromAscii(USER); + uri = OUString::createFromAscii(USER_URI); + bAppendScriptsPart = true; + } + else if ( m_sLocation.equalsAscii(USER_UNO_PACKAGES)) + { + test = OUString::createFromAscii("uno_packages"); + uri = OUString::createFromAscii(USER_URI); + uri = uri.concat(OUString::createFromAscii(USER_UNO_PACKAGES_DIR)); + } + else if (m_sLocation.equalsAscii(SHARE)) + { + test = OUString::createFromAscii(SHARE); + uri = OUString::createFromAscii(SHARE_URI); + bAppendScriptsPart = true; + } + else if (m_sLocation.equalsAscii(SHARE_UNO_PACKAGES)) + { + test = OUString::createFromAscii("uno_packages"); + uri = OUString::createFromAscii(SHARE_UNO_PACKAGES_URI); + } + else if (m_sLocation.indexOf(OUString::createFromAscii(TDOC_SCHEME)) == 0) + { + m_sBaseURI = m_sLocation.concat( SCRIPTS_PART ); + m_sLocation = OUString::createFromAscii( DOCUMENT ); + return true; + } + else + { + return false; + } + + if ( !m_xSimpleFileAccess->exists( uri ) || + !m_xSimpleFileAccess->isFolder( uri ) ) + { + return false; + } + + uno::Sequence< OUString > children = + m_xSimpleFileAccess->getFolderContents( uri, true ); + + for ( sal_Int32 i = 0; i < children.getLength(); i++ ) + { + OUString child = children[i]; + sal_Int32 idx = child.lastIndexOf(test); + + // OSL_TRACE("Trying: %s", PRTSTR(child)); + // OSL_TRACE("idx=%d, testlen=%d, children=%d", + // idx, test.getLength(), child.getLength()); + + if ( idx != -1 && (idx + test.getLength()) == child.getLength() ) + { + // OSL_TRACE("FOUND PATH: %s", PRTSTR(child)); + if ( bAppendScriptsPart ) + { + m_sBaseURI = child.concat( SCRIPTS_PART ); + } + else + { + m_sBaseURI = child; + } + return true; + } + } + return false; +} + +OUString +ScriptingFrameworkURIHelper::getLanguagePart(const OUString& rStorageURI) +{ + OUString result; + + sal_Int32 idx = rStorageURI.indexOf(m_sBaseURI); + sal_Int32 len = m_sBaseURI.getLength() + 1; + + if ( idx != -1 ) + { + result = rStorageURI.copy(idx + len); + result = result.replace('/', '|'); + } + return result; +} + +OUString +ScriptingFrameworkURIHelper::getLanguagePath(const OUString& rLanguagePart) +{ + OUString result; + result = rLanguagePart.replace('|', '/'); + return result; +} + +OUString SAL_CALL +ScriptingFrameworkURIHelper::getScriptURI(const OUString& rStorageURI) + throw( lang::IllegalArgumentException, uno::RuntimeException ) +{ + ::rtl::OUStringBuffer buf(120); + + buf.appendAscii("vnd.sun.star.script:"); + buf.append(getLanguagePart(rStorageURI)); + buf.appendAscii("?language="); + buf.append(m_sLanguage); + buf.appendAscii("&location="); + buf.append(m_sLocation); + + return buf.makeStringAndClear(); +} + +OUString SAL_CALL +ScriptingFrameworkURIHelper::getStorageURI(const OUString& rScriptURI) + throw( lang::IllegalArgumentException, uno::RuntimeException ) +{ + OUString sLanguagePart; + try + { + uno::Reference < uri::XVndSunStarScriptUrl > xURI( + m_xUriReferenceFactory->parse( rScriptURI ), uno::UNO_QUERY_THROW ); + sLanguagePart = xURI->getName(); + } + catch ( uno::Exception& ) + { + throw lang::IllegalArgumentException( + OUString::createFromAscii( "Script URI not valid" ), + uno::Reference< uno::XInterface >(), 1 ); + } + + ::rtl::OUStringBuffer buf(120); + buf.append(m_sBaseURI); + buf.append(OUString::createFromAscii("/")); + buf.append(getLanguagePath(sLanguagePart)); + + OUString result = buf.makeStringAndClear(); + + return result; +} + +OUString SAL_CALL +ScriptingFrameworkURIHelper::getRootStorageURI() + throw( uno::RuntimeException ) +{ + return m_sBaseURI; +} + +OUString SAL_CALL +ScriptingFrameworkURIHelper::getImplementationName() + throw( uno::RuntimeException ) +{ + return OUString::createFromAscii( + "com.sun.star.script.provider.ScriptURIHelper" ); +} + +sal_Bool SAL_CALL +ScriptingFrameworkURIHelper::supportsService( const OUString& serviceName ) + throw( uno::RuntimeException ) +{ + OUString m_sServiceName = OUString::createFromAscii( + "com.sun.star.script.provider.ScriptURIHelper" ); + + if ( serviceName.equals( m_sServiceName ) ) + { + return sal_True; + } + return sal_False; +} + +uno::Sequence< ::rtl::OUString > SAL_CALL +ScriptingFrameworkURIHelper::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + ::rtl::OUString serviceNameList[] = { + ::rtl::OUString::createFromAscii( + "com.sun.star.script.provider.ScriptURIHelper" ) }; + + uno::Sequence< ::rtl::OUString > serviceNames = uno::Sequence < + ::rtl::OUString > ( serviceNameList, 1 ); + + return serviceNames; +} +} diff --git a/scripting/source/provider/URIHelper.hxx b/scripting/source/provider/URIHelper.hxx new file mode 100644 index 000000000000..2b0b38a4de0e --- /dev/null +++ b/scripting/source/provider/URIHelper.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_PROVIDER_XSCRIPTURIHELPER_HXX_ +#define _FRAMEWORK_SCRIPT_PROVIDER_XSCRIPTURIHELPER_HXX_ + +#include <com/sun/star/script/provider/XScriptURIHelper.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> + +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase3.hxx> + +namespace func_provider +{ + +#define css ::com::sun::star + +class ScriptingFrameworkURIHelper : + public ::cppu::WeakImplHelper3< + css::script::provider::XScriptURIHelper, + css::lang::XServiceInfo, + css::lang::XInitialization > +{ +private: + + css::uno::Reference< css::ucb::XSimpleFileAccess > m_xSimpleFileAccess; + css::uno::Reference<css::uri::XUriReferenceFactory> m_xUriReferenceFactory; + + ::rtl::OUString m_sLanguage; + ::rtl::OUString m_sLocation; + ::rtl::OUString m_sBaseURI; + + ::rtl::OUString SCRIPTS_PART; + + bool initBaseURI(); + ::rtl::OUString getLanguagePart(const ::rtl::OUString& rStorageURI); + ::rtl::OUString getLanguagePath(const ::rtl::OUString& rLanguagePart); + +public: + + ScriptingFrameworkURIHelper( + const css::uno::Reference< css::uno::XComponentContext >& xContext ) + throw( css::uno::RuntimeException ); + + ~ScriptingFrameworkURIHelper(); + + virtual void SAL_CALL + initialize( const css::uno::Sequence < css::uno::Any > & args ) + throw ( css::uno::Exception, css::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL + getRootStorageURI() + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL + getScriptURI( const ::rtl::OUString& rStorageURI ) + throw( css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL + getStorageURI( const ::rtl::OUString& rScriptURI ) + throw( css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw( css::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& ServiceName ) + throw( css::uno::RuntimeException ); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw( css::uno::RuntimeException ); +}; + +} // namespace func_provider +#endif //_FRAMEWORK_SCRIPT_PROVIDER_XSCRIPTURIHELPER_HXX_ diff --git a/scripting/source/provider/exports.dxp b/scripting/source/provider/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/scripting/source/provider/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/scripting/source/provider/makefile.mk b/scripting/source/provider/makefile.mk new file mode 100644 index 000000000000..a63ae078d837 --- /dev/null +++ b/scripting/source/provider/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= scripting +TARGET= provider +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=\ + $(SLO)$/MasterScriptProvider.obj\ + $(SLO)$/URIHelper.obj\ + $(SLO)$/ActiveMSPList.obj\ + $(SLO)$/ProviderCache.obj\ + $(SLO)$/MasterScriptProviderFactory.obj\ + $(SLO)$/BrowseNodeFactoryImpl.obj\ + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/provider/provider.xml b/scripting/source/provider/provider.xml new file mode 100755 index 000000000000..47127d879cd2 --- /dev/null +++ b/scripting/source/provider/provider.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> ScriptProvider </module-name> + <component-description> + <author> Noel Power</author> + <name> com.sun.star.script.provider.ScriptProvider </name> + <description> + This component is part of the Scripting Framework +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="drafts"/> + <supported-service> com.sun.star.script.provider.ScriptProvider </supported-service> + <type> com.sun.star.beans.XPropertySet </type> + <type> com.sun.star.uno.Exception </type> + <type> com.sun.star.io.IOException </type> + <type> com.sun.star.io.XStream </type> + <type> com.sun.star.script.provider.XScript </type> + <type> com.sun.star.script.provider.XScriptProvider </type> + <type> com.sun.star.script.browse.XBrowseNode </type> + <type> com.sun.star.script.browse.BrowseNodeTypes </type> + <type> com.sun.star.uri.XUriReference </type> + <type> com.sun.star.uri.XUriReferenceFactory </type> + <type> com.sun.star.uri.XVndSunStarScriptUrl </type> + + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper2$(COM) </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/scripting/source/pyprov/mailmerge.py b/scripting/source/pyprov/mailmerge.py new file mode 100644 index 000000000000..6592a59d1843 --- /dev/null +++ b/scripting/source/pyprov/mailmerge.py @@ -0,0 +1,440 @@ +# Caolan McNamara caolanm@redhat.com +# a simple email mailmerge component + +# manual installation for hackers, not necessary for users +# cp mailmerge.py /usr/lib/openoffice.org2.0/program +# cd /usr/lib/openoffice.org2.0/program +# ./unopkg add --shared mailmerge.py +# edit ~/.openoffice.org2/user/registry/data/org/openoffice/Office/Writer.xcu +# and change EMailSupported to as follows... +# <prop oor:name="EMailSupported" oor:type="xs:boolean"> +# <value>true</value> +# </prop> + +import unohelper +import uno +import re + +#to implement com::sun::star::mail::XMailServiceProvider +#and +#to implement com.sun.star.mail.XMailMessage + +from com.sun.star.mail import XMailServiceProvider +from com.sun.star.mail import XMailService +from com.sun.star.mail import XSmtpService +from com.sun.star.mail import XConnectionListener +from com.sun.star.mail import XAuthenticator +from com.sun.star.mail import XMailMessage +from com.sun.star.mail.MailServiceType import SMTP +from com.sun.star.mail.MailServiceType import POP3 +from com.sun.star.mail.MailServiceType import IMAP +from com.sun.star.uno import XCurrentContext +from com.sun.star.lang import IllegalArgumentException +from com.sun.star.lang import EventObject +from com.sun.star.mail import SendMailMessageFailedException + +from email.MIMEBase import MIMEBase +from email.Message import Message +from email import Encoders +from email.Header import Header +from email.MIMEMultipart import MIMEMultipart +from email.Utils import formatdate +from email.Utils import parseaddr + +import sys, smtplib, imaplib, poplib + +dbg = False + +class PyMailSMTPService(unohelper.Base, XSmtpService): + def __init__( self, ctx ): + self.ctx = ctx + self.listeners = [] + self.supportedtypes = ('Insecure', 'Ssl') + self.server = None + self.connectioncontext = None + self.notify = EventObject() + if dbg: + print >> sys.stderr, "PyMailSMPTService init" + def addConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailSMPTService addConnectionListener" + self.listeners.append(xListener) + def removeConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailSMPTService removeConnectionListener" + self.listeners.remove(xListener) + def getSupportedConnectionTypes(self): + if dbg: + print >> sys.stderr, "PyMailSMPTService getSupportedConnectionTypes" + return self.supportedtypes + def connect(self, xConnectionContext, xAuthenticator): + self.connectioncontext = xConnectionContext + if dbg: + print >> sys.stderr, "PyMailSMPTService connect" + server = xConnectionContext.getValueByName("ServerName") + if dbg: + print >> sys.stderr, server + port = xConnectionContext.getValueByName("Port") + if dbg: + print >> sys.stderr, port + self.server = smtplib.SMTP(server, port) + if dbg: + self.server.set_debuglevel(1) + connectiontype = xConnectionContext.getValueByName("ConnectionType") + if dbg: + print >> sys.stderr, connectiontype + if connectiontype == 'Ssl': + self.server.ehlo() + self.server.starttls() + self.server.ehlo() + + user = xAuthenticator.getUserName().encode('ascii') + password = xAuthenticator.getPassword().encode('ascii') + if user != '': + if dbg: + print >> sys.stderr, 'Logging in, username of', user + self.server.login(user, password) + + for listener in self.listeners: + listener.connected(self.notify) + def disconnect(self): + if dbg: + print >> sys.stderr, "PyMailSMPTService disconnect" + if self.server: + self.server.quit() + self.server = None + for listener in self.listeners: + listener.disconnected(self.notify) + def isConnected(self): + if dbg: + print >> sys.stderr, "PyMailSMPTService isConnected" + return self.server != None + def getCurrentConnectionContext(self): + if dbg: + print >> sys.stderr, "PyMailSMPTService getCurrentConnectionContext" + return self.connectioncontext + def sendMailMessage(self, xMailMessage): + COMMASPACE = ', ' + + if dbg: + print >> sys.stderr, "PyMailSMPTService sendMailMessage" + recipients = xMailMessage.getRecipients() + sendermail = xMailMessage.SenderAddress + sendername = xMailMessage.SenderName + subject = xMailMessage.Subject + ccrecipients = xMailMessage.getCcRecipients() + bccrecipients = xMailMessage.getBccRecipients() + if dbg: + print >> sys.stderr, "PyMailSMPTService subject", subject + print >> sys.stderr, "PyMailSMPTService from", sendername.encode('utf-8') + print >> sys.stderr, "PyMailSMTPService from", sendermail + print >> sys.stderr, "PyMailSMPTService send to", recipients + + attachments = xMailMessage.getAttachments() + + textmsg = Message() + + content = xMailMessage.Body + flavors = content.getTransferDataFlavors() + if dbg: + print >> sys.stderr, "PyMailSMPTService flavors len", len(flavors) + + #Use first flavor that's sane for an email body + for flavor in flavors: + if flavor.MimeType.find('text/html') != -1 or flavor.MimeType.find('text/plain') != -1: + if dbg: + print >> sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType + textbody = content.getTransferData(flavor) + try: + textbody = textbody.value + except: + pass + textbody = textbody.encode('utf-8') + + if len(textbody): + mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType) + if mimeEncoding.find('charset=UTF-8') == -1: + mimeEncoding = mimeEncoding + "; charset=UTF-8" + textmsg['Content-Type'] = mimeEncoding + textmsg['MIME-Version'] = '1.0' + textmsg.set_payload(textbody) + + break + + if (len(attachments)): + msg = MIMEMultipart() + msg.epilogue = '' + msg.attach(textmsg) + else: + msg = textmsg + + hdr = Header(sendername, 'utf-8') + hdr.append('<'+sendermail+'>','us-ascii') + msg['Subject'] = subject + msg['From'] = hdr + msg['To'] = COMMASPACE.join(recipients) + if len(ccrecipients): + msg['Cc'] = COMMASPACE.join(ccrecipients) + if xMailMessage.ReplyToAddress != '': + msg['Reply-To'] = xMailMessage.ReplyToAddress + + mailerstring = "OpenOffice.org 2.0 via Caolan's mailmerge component" + try: + ctx = uno.getComponentContext() + aConfigProvider = ctx.ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider") + prop = uno.createUnoStruct('com.sun.star.beans.PropertyValue') + prop.Name = "nodepath" + prop.Value = "/org.openoffice.Setup/Product" + aSettings = aConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", + (prop,)) + mailerstring = aSettings.getByName("ooName") + " " + \ + aSettings.getByName("ooSetupVersion") + " via Caolan's mailmerge component" + except: + pass + + msg['X-Mailer'] = mailerstring + msg['Date'] = formatdate(localtime=True) + + for attachment in attachments: + content = attachment.Data + flavors = content.getTransferDataFlavors() + flavor = flavors[0] + ctype = flavor.MimeType + maintype, subtype = ctype.split('/', 1) + msgattachment = MIMEBase(maintype, subtype) + data = content.getTransferData(flavor) + msgattachment.set_payload(data) + Encoders.encode_base64(msgattachment) + msgattachment.add_header('Content-Disposition', 'attachment', \ + filename=attachment.ReadableName) + msg.attach(msgattachment) + + uniquer = {} + for key in recipients: + uniquer[key] = True + if len(ccrecipients): + for key in ccrecipients: + uniquer[key] = True + if len(bccrecipients): + for key in bccrecipients: + uniquer[key] = True + truerecipients = uniquer.keys() + + if dbg: + print >> sys.stderr, "PyMailSMPTService recipients are", truerecipients + + self.server.sendmail(sendermail, truerecipients, msg.as_string()) + +class PyMailIMAPService(unohelper.Base, XMailService): + def __init__( self, ctx ): + self.ctx = ctx + self.listeners = [] + self.supportedtypes = ('Insecure', 'Ssl') + self.server = None + self.connectioncontext = None + if dbg: + print >> sys.stderr, "PyMailIMAPService init" + def addConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailIMAPService addConnectionListener" + self.listeners.append(xListener) + def removeConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailIMAPService removeConnectionListener" + self.listeners.remove(xListener) + def getSupportedConnectionTypes(self): + if dbg: + print >> sys.stderr, "PyMailIMAPService getSupportedConnectionTypes" + return self.supportedtypes + def connect(self, xConnectionContext, xAuthenticator): + if dbg: + print >> sys.stderr, "PyMailIMAPService connect" + + self.connectioncontext = xConnectionContext + server = xConnectionContext.getValueByName("ServerName") + if dbg: + print >> sys.stderr, server + port = xConnectionContext.getValueByName("Port") + if dbg: + print >> sys.stderr, port + connectiontype = xConnectionContext.getValueByName("ConnectionType") + if dbg: + print >> sys.stderr, connectiontype + print >> sys.stderr, "BEFORE" + if connectiontype == 'Ssl': + self.server = imaplib.IMAP4_SSL(server, port) + else: + self.server = imaplib.IMAP4(server, port) + print >> sys.stderr, "AFTER" + + user = xAuthenticator.getUserName().encode('ascii') + password = xAuthenticator.getPassword().encode('ascii') + if user != '': + if dbg: + print >> sys.stderr, 'Logging in, username of', user + self.server.login(user, password) + + for listener in self.listeners: + listener.connected(self.notify) + def disconnect(self): + if dbg: + print >> sys.stderr, "PyMailIMAPService disconnect" + if self.server: + self.server.logout() + self.server = None + for listener in self.listeners: + listener.disconnected(self.notify) + def isConnected(self): + if dbg: + print >> sys.stderr, "PyMailIMAPService isConnected" + return self.server != None + def getCurrentConnectionContext(self): + if dbg: + print >> sys.stderr, "PyMailIMAPService getCurrentConnectionContext" + return self.connectioncontext + +class PyMailPOP3Service(unohelper.Base, XMailService): + def __init__( self, ctx ): + self.ctx = ctx + self.listeners = [] + self.supportedtypes = ('Insecure', 'Ssl') + self.server = None + self.connectioncontext = None + if dbg: + print >> sys.stderr, "PyMailPOP3Service init" + def addConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailPOP3Service addConnectionListener" + self.listeners.append(xListener) + def removeConnectionListener(self, xListener): + if dbg: + print >> sys.stderr, "PyMailPOP3Service removeConnectionListener" + self.listeners.remove(xListener) + def getSupportedConnectionTypes(self): + if dbg: + print >> sys.stderr, "PyMailPOP3Service getSupportedConnectionTypes" + return self.supportedtypes + def connect(self, xConnectionContext, xAuthenticator): + if dbg: + print >> sys.stderr, "PyMailPOP3Service connect" + + self.connectioncontext = xConnectionContext + server = xConnectionContext.getValueByName("ServerName") + if dbg: + print >> sys.stderr, server + port = xConnectionContext.getValueByName("Port") + if dbg: + print >> sys.stderr, port + connectiontype = xConnectionContext.getValueByName("ConnectionType") + if dbg: + print >> sys.stderr, connectiontype + print >> sys.stderr, "BEFORE" + if connectiontype == 'Ssl': + self.server = poplib.POP3_SSL(server, port) + else: + self.server = poplib.POP3(server, port) + print >> sys.stderr, "AFTER" + + user = xAuthenticator.getUserName().encode('ascii') + password = xAuthenticator.getPassword().encode('ascii') + if dbg: + print >> sys.stderr, 'Logging in, username of', user + self.server.user(user) + self.server.pass_(user, password) + + for listener in self.listeners: + listener.connected(self.notify) + def disconnect(self): + if dbg: + print >> sys.stderr, "PyMailPOP3Service disconnect" + if self.server: + self.server.quit() + self.server = None + for listener in self.listeners: + listener.disconnected(self.notify) + def isConnected(self): + if dbg: + print >> sys.stderr, "PyMailPOP3Service isConnected" + return self.server != None + def getCurrentConnectionContext(self): + if dbg: + print >> sys.stderr, "PyMailPOP3Service getCurrentConnectionContext" + return self.connectioncontext + +class PyMailServiceProvider(unohelper.Base, XMailServiceProvider): + def __init__( self, ctx ): + if dbg: + print >> sys.stderr, "PyMailServiceProvider init" + self.ctx = ctx + def create(self, aType): + if dbg: + print >> sys.stderr, "PyMailServiceProvider create with", aType + if aType == SMTP: + return PyMailSMTPService(self.ctx); + elif aType == POP3: + return PyMailPOP3Service(self.ctx); + elif aType == IMAP: + return PyMailIMAPService(self.ctx); + else: + print >> sys.stderr, "PyMailServiceProvider, unknown TYPE", aType + +class PyMailMessage(unohelper.Base, XMailMessage): + def __init__( self, ctx, sTo='', sFrom='', Subject='', Body=None, aMailAttachment=None ): + if dbg: + print >> sys.stderr, "PyMailMessage init" + self.ctx = ctx + + self.recipients = sTo, + self.ccrecipients = () + self.bccrecipients = () + self.aMailAttachments = () + if aMailAttachment != None: + self.aMailAttachments = aMailAttachment, + + self.SenderName, self.SenderAddress = parseaddr(sFrom) + self.ReplyToAddress = sFrom + self.Subject = Subject + self.Body = Body + if dbg: + print >> sys.stderr, "post PyMailMessage init" + def addRecipient( self, recipient ): + if dbg: + print >> sys.stderr, "PyMailMessage.addRecipient", recipient + self.recipients = self.recipients, recipient + def addCcRecipient( self, ccrecipient ): + if dbg: + print >> sys.stderr, "PyMailMessage.addCcRecipient", ccrecipient + self.ccrecipients = self.ccrecipients, ccrecipient + def addBccRecipient( self, bccrecipient ): + if dbg: + print >> sys.stderr, "PyMailMessage.addBccRecipient", bccrecipient + self.bccrecipients = self.bccrecipients, bccrecipient + def getRecipients( self ): + if dbg: + print >> sys.stderr, "PyMailMessage.getRecipients", self.recipients + return self.recipients + def getCcRecipients( self ): + if dbg: + print >> sys.stderr, "PyMailMessage.getCcRecipients", self.ccrecipients + return self.ccrecipients + def getBccRecipients( self ): + if dbg: + print >> sys.stderr, "PyMailMessage.getBccRecipients", self.bccrecipients + return self.bccrecipients + def addAttachment( self, aMailAttachment ): + if dbg: + print >> sys.stderr, "PyMailMessage.addAttachment" + self.aMailAttachments = self.aMailAttachments, aMailAttachment + def getAttachments( self ): + if dbg: + print >> sys.stderr, "PyMailMessage.getAttachments" + return self.aMailAttachments + +# pythonloader looks for a static g_ImplementationHelper variable +g_ImplementationHelper = unohelper.ImplementationHelper() +g_ImplementationHelper.addImplementation( \ + PyMailServiceProvider, "org.openoffice.pyuno.MailServiceProvider", + ("com.sun.star.mail.MailServiceProvider",),) +g_ImplementationHelper.addImplementation( \ + PyMailMessage, "org.openoffice.pyuno.MailMessage", + ("com.sun.star.mail.MailMessage",),) diff --git a/scripting/source/pyprov/makefile.mk b/scripting/source/pyprov/makefile.mk new file mode 100644 index 000000000000..3c0278595181 --- /dev/null +++ b/scripting/source/pyprov/makefile.mk @@ -0,0 +1,49 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=scripting +TARGET=pyprov + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + + +# --- Targets ------------------------------------------------------ +ALL : ALLTAR \ + $(DLLDEST)$/pythonscript.py \ + $(DLLDEST)$/officehelper.py \ + $(DLLDEST)$/mailmerge.py + +$(DLLDEST)$/%.py: %.py + cp $? $@ + +.INCLUDE : target.mk diff --git a/scripting/source/pyprov/officehelper.py b/scripting/source/pyprov/officehelper.py new file mode 100644 index 000000000000..610ac5f9dbe7 --- /dev/null +++ b/scripting/source/pyprov/officehelper.py @@ -0,0 +1,93 @@ +### ************************************************************************* +### * +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +### ************************************************************************/ + +# +# Translated to python from "Bootstrap.java" by Kim Kulak +# + +import os +import random +from sys import platform +from time import sleep + +import uno +from com.sun.star.connection import NoConnectException +from com.sun.star.uno import Exception as UnoException + + +class BootstrapException(UnoException): + pass + +def bootstrap(): + """Bootstrap OOo and PyUNO Runtime. + The soffice process is started opening a named pipe of random name, then the local context is used + to access the pipe. This function directly returns the remote component context, from whereon you can + get the ServiceManager by calling getServiceManager() on the returned object. + """ + try: + # soffice script used on *ix, Mac; soffice.exe used on Windoof + if "UNO_PATH" in os.environ: + sOffice = os.environ["UNO_PATH"] + else: + sOffice = "" # lets hope for the best + sOffice = os.path.join(sOffice, "soffice") + if platform.startswith("win"): + sOffice += ".exe" + + # Generate a random pipe name. + random.seed() + sPipeName = "uno" + str(random.random())[2:] + + # Start the office proces, don't check for exit status since an exception is caught anyway if the office terminates unexpectedly. + cmdArray = (sOffice, "-nologo", "-nodefault", "".join(["-accept=pipe,name=", sPipeName, ";urp;"])) + os.spawnv(os.P_NOWAIT, sOffice, cmdArray) + + # --------- + + xLocalContext = uno.getComponentContext() + resolver = xLocalContext.ServiceManager.createInstanceWithContext( + "com.sun.star.bridge.UnoUrlResolver", xLocalContext) + sConnect = "".join(["uno:pipe,name=", sPipeName, ";urp;StarOffice.ComponentContext"]) + + # Wait until an office is started, but loop only nLoop times (can we do this better???) + nLoop = 20 + while True: + try: + xContext = resolver.resolve(sConnect) + break + except NoConnectException: + nLoop -= 1 + if nLoop <= 0: + raise BootstrapException("Cannot connect to soffice server.", None) + sleep(0.5) # Sleep 1/2 second. + + except BootstrapException: + raise + except Exception, e: # Any other exception + raise BootstrapException("Caught exception " + str(e), None) + + return xContext diff --git a/scripting/source/pyprov/pythonscript.py b/scripting/source/pyprov/pythonscript.py new file mode 100644 index 000000000000..88e0a9efbc9d --- /dev/null +++ b/scripting/source/pyprov/pythonscript.py @@ -0,0 +1,984 @@ +# XScript implementation for python +import uno +import unohelper +import sys +import os +import imp +import time +import compiler + +class LogLevel: + NONE = 0 + ERROR = 1 + DEBUG = 2 + +# Configuration ---------------------------------------------------- +LogLevel.use = LogLevel.NONE # production level +#LogLevel.use = LogLevel.ERROR # for script developers +#LogLevel.use = LogLevel.DEBUG # for script framework developers +LOG_STDOUT = True # True, writes to stdout (difficult on windows) + # False, writes to user/Scripts/python/log.txt +ENABLE_EDIT_DIALOG=False # offers a minimal editor for editing. +#------------------------------------------------------------------- + +def encfile(uni): + return uni.encode( sys.getfilesystemencoding()) + +def lastException2String(): + (excType,excInstance,excTraceback) = sys.exc_info() + ret = str(excType) + ": "+str(excInstance) + "\n" + \ + uno._uno_extract_printable_stacktrace( excTraceback ) + return ret + +def logLevel2String( level ): + ret = " NONE" + if level == LogLevel.ERROR: + ret = "ERROR" + elif level >= LogLevel.DEBUG: + ret = "DEBUG" + return ret + +def getLogTarget(): + ret = sys.stdout + if not LOG_STDOUT: + try: + pathSubst = uno.getComponentContext().ServiceManager.createInstance( + "com.sun.star.util.PathSubstitution" ) + userInstallation = pathSubst.getSubstituteVariableValue( "user" ) + if len( userInstallation ) > 0: + systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" ) + ret = file( systemPath , "a" ) + except Exception,e: + print "Exception during creation of pythonscript logfile: "+ lastException2String() + "\n, delagating log to stdout\n" + return ret + +class Logger(LogLevel): + def __init__(self , target ): + self.target = target + + def isDebugLevel( self ): + return self.use >= self.DEBUG + + def debug( self, msg ): + if self.isDebugLevel(): + self.log( self.DEBUG, msg ) + + def isErrorLevel( self ): + return self.use >= self.ERROR + + def error( self, msg ): + if self.isErrorLevel(): + self.log( self.ERROR, msg ) + + def log( self, level, msg ): + if self.use >= level: + try: + self.target.write( + time.asctime() + + " [" + + logLevel2String( level ) + + "] " + + encfile(msg) + + "\n" ) + self.target.flush() + except Exception,e: + print "Error during writing to stdout: " +lastException2String() + "\n" + +log = Logger( getLogTarget() ) + +log.debug( "pythonscript loading" ) + +#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider +from com.sun.star.uno import RuntimeException +from com.sun.star.lang import XServiceInfo +from com.sun.star.io import IOException +from com.sun.star.ucb import CommandAbortedException, XCommandEnvironment, XProgressHandler +from com.sun.star.task import XInteractionHandler +from com.sun.star.beans import XPropertySet +from com.sun.star.container import XNameContainer +from com.sun.star.xml.sax import XDocumentHandler, InputSource +from com.sun.star.uno import Exception as UnoException +from com.sun.star.script import XInvocation +from com.sun.star.awt import XActionListener + +from com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException +from com.sun.star.script.browse import XBrowseNode +from com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT +from com.sun.star.util import XModifyListener + +LANGUAGENAME = "Python" +GLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT" +CALLABLE_CONTAINER_NAME = "g_exportedScripts" + +# pythonloader looks for a static g_ImplementationHelper variable +g_ImplementationHelper = unohelper.ImplementationHelper() +g_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME + + + +BLOCK_SIZE = 65536 +def readTextFromStream( inputStream ): + # read the file + code = uno.ByteSequence( "" ) + while True: + read,out = inputStream.readBytes( None , BLOCK_SIZE ) + code = code + out + if read < BLOCK_SIZE: + break + return code.value + +def toIniName( str ): + # TODO: what is the official way to get to know whether i am on the windows platform ? + if( hasattr(sys , "dllhandle") ): + return str + ".ini" + return str + "rc" + + +""" definition: storageURI is the system dependent, absolute file url, where the script is stored on disk + scriptURI is the system independent uri +""" +class MyUriHelper: + + def __init__( self, ctx, location ): + self.s_UriMap = \ + { "share" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" + toIniName( "bootstrap") + "::BaseInstallation}/share/Scripts/python" , \ + "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \ + "user" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \ + "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" } + self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx) + if location.startswith( "vnd.sun.star.tdoc" ): + self.m_baseUri = location + "/Scripts/python" + self.m_scriptUriLocation = "document" + else: + self.m_baseUri = expandUri( self.s_UriMap[location] ) + self.m_scriptUriLocation = location + log.isDebugLevel() and log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation ) + + def getRootStorageURI( self ): + return self.m_baseUri + + def getStorageURI( self, scriptURI ): + return self.scriptURI2StorageUri(scriptURI) + + def getScriptURI( self, storageURI ): + return self.storageURI2ScriptUri(storageURI) + + def storageURI2ScriptUri( self, storageURI ): + if not storageURI.startswith( self.m_baseUri ): + message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'" + log.isDebugLevel() and log.debug( message ) + raise RuntimeException( message ) + + ret = "vnd.sun.star.script:" + \ + storageURI[len(self.m_baseUri)+1:].replace("/","|") + \ + "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation + log.isDebugLevel() and log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret ) + return ret + + def scriptURI2StorageUri( self, scriptURI ): + try: + myUri = self.m_uriRefFac.parse(scriptURI) + ret = self.m_baseUri + "/" + myUri.getName().replace( "|", "/" ) + log.isDebugLevel() and log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret ) + return ret + except UnoException, e: + log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message) + raise RuntimeException( "pythonscript:scriptURI2StorageUri: " +e.getMessage(), None ) + except Exception, e: + log.error( "error during converting scriptURI="+scriptURI + ": " + str(e)) + raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), None ) + + +class ModuleEntry: + def __init__( self, lastRead, module ): + self.lastRead = lastRead + self.module = module + +def hasChanged( oldDate, newDate ): + return newDate.Year > oldDate.Year or \ + newDate.Month > oldDate.Month or \ + newDate.Day > oldDate.Day or \ + newDate.Hours > oldDate.Hours or \ + newDate.Minutes > oldDate.Minutes or \ + newDate.Seconds > oldDate.Seconds or \ + newDate.HundredthSeconds > oldDate.HundredthSeconds + +def ensureSourceState( code ): + if not code.endswith( "\n" ): + code = code + "\n" + code = code.replace( "\r", "" ) + return code + + +def checkForPythonPathBesideScript( url ): + if url.startswith( "file:" ): + path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); + log.log( LogLevel.DEBUG, "checking for existence of " + path ) + if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path: + log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) + sys.path.append( path ) + + path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); + log.log( LogLevel.DEBUG, "checking for existence of " + path ) + if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path: + log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) + sys.path.append( path ) + + +class ScriptContext(unohelper.Base): + def __init__( self, ctx, doc ): + self.ctx = ctx + self.doc = doc + + # XScriptContext + def getDocument(self): + return self.getDesktop().getCurrentComponent() + + def getDesktop(self): + return self.ctx.ServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", self.ctx ) + + def getComponentContext(self): + return self.ctx + +#---------------------------------- +# Global Module Administration +# does not fit together with script +# engine lifetime management +#---------------------------------- +#g_scriptContext = ScriptContext( uno.getComponentContext(), None ) +#g_modules = {} +#def getModuleByUrl( url, sfa ): +# entry = g_modules.get(url) +# load = True +# lastRead = sfa.getDateTimeModified( url ) +# if entry: +# if hasChanged( entry.lastRead, lastRead ): +# log.isDebugLevel() and log.debug("file " + url + " has changed, reloading") +# else: +# load = False +# +# if load: +# log.isDebugLevel() and log.debug( "opening >" + url + "<" ) +# +# code = readTextFromStream( sfa.openFileRead( url ) ) + + # execute the module +# entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") ) +# entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext +# entry.module.__file__ = url +# exec code in entry.module.__dict__ +# g_modules[ url ] = entry +# log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) ) +# return entry.module + +class ProviderContext: + def __init__( self, storageType, sfa, uriHelper, scriptContext ): + self.storageType = storageType + self.sfa = sfa + self.uriHelper = uriHelper + self.scriptContext = scriptContext + self.modules = {} + self.rootUrl = None + self.mapPackageName2Path = None + + def getTransientPartFromUrl( self, url ): + rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) + return rest[0:rest.find("/")] + + def getPackageNameFromUrl( self, url ): + rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) + start = rest.find("/") +1 + return rest[start:rest.find("/",start)] + + + def removePackageByUrl( self, url ): + items = self.mapPackageName2Path.items() + for i in items: + if url in i[1].pathes: + self.mapPackageName2Path.pop(i[0]) + break + + def addPackageByUrl( self, url ): + packageName = self.getPackageNameFromUrl( url ) + transientPart = self.getTransientPartFromUrl( url ) + log.isDebugLevel() and log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl ) + if self.mapPackageName2Path.has_key( packageName ): + package = self.mapPackageName2Path[ packageName ] + package.pathes = package.pathes + (url, ) + else: + package = Package( (url,), transientPart) + self.mapPackageName2Path[ packageName ] = package + + def isUrlInPackage( self, url ): + values = self.mapPackageName2Path.values() + for i in values: +# print "checking " + url + " in " + str(i.pathes) + if url in i.pathes: + return True +# print "false" + return False + + def setPackageAttributes( self, mapPackageName2Path, rootUrl ): + self.mapPackageName2Path = mapPackageName2Path + self.rootUrl = rootUrl + + def getPersistentUrlFromStorageUrl( self, url ): + # package name is the second directory + ret = url + if self.rootUrl: + pos = len( self.rootUrl) +1 + ret = url[0:pos]+url[url.find("/",pos)+1:len(url)] + log.isDebugLevel() and log.debug( "getPersistentUrlFromStorageUrl " + url + " -> "+ ret) + return ret + + def getStorageUrlFromPersistentUrl( self, url): + ret = url + if self.rootUrl: + pos = len(self.rootUrl)+1 + packageName = url[pos:url.find("/",pos+1)] + package = self.mapPackageName2Path[ packageName ] + ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)] + log.isDebugLevel() and log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret) + return ret + + def getFuncsByUrl( self, url ): + src = readTextFromStream( self.sfa.openFileRead( url ) ) + checkForPythonPathBesideScript( url[0:url.rfind('/')] ) + src = ensureSourceState( src ) + + code = compiler.parse( src ) + + allFuncs = [] + + if code == None: + return allFuncs + + g_exportedScripts = [] + for node in code.node.nodes: + if node.__class__.__name__ == 'Function': + allFuncs.append(node.name) + elif node.__class__.__name__ == 'Assign': + for assignee in node.nodes: + if assignee.name == 'g_exportedScripts': + for item in node.expr: + if item.__class__.__name__ == 'Name': + g_exportedScripts.append(item.name) + return g_exportedScripts + + return allFuncs + + def getModuleByUrl( self, url ): + entry = self.modules.get(url) + load = True + lastRead = self.sfa.getDateTimeModified( url ) + if entry: + if hasChanged( entry.lastRead, lastRead ): + log.isDebugLevel() and log.debug( "file " + url + " has changed, reloading" ) + else: + load = False + + if load: + log.isDebugLevel() and log.debug( "opening >" + url + "<" ) + + src = readTextFromStream( self.sfa.openFileRead( url ) ) + checkForPythonPathBesideScript( url[0:url.rfind('/')] ) + src = ensureSourceState( src ) + + # execute the module + entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") ) + entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext + + code = None + if url.startswith( "file:" ): + code = compile( src, encfile(uno.fileUrlToSystemPath( url ) ), "exec" ) + else: + code = compile( src, url, "exec" ) + exec code in entry.module.__dict__ + entry.module.__file__ = url + self.modules[ url ] = entry + log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) ) + return entry.module + +#-------------------------------------------------- +def isScript( candidate ): + ret = False + if isinstance( candidate, type(isScript) ): + ret = True + return ret + +#------------------------------------------------------- +class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ): + def __init__( self, provCtx, uri, fileName, funcName ): + self.fileName = fileName + self.funcName = funcName + self.provCtx = provCtx + self.uri = uri + + def getName( self ): + return self.funcName + + def getChildNodes(self): + return () + + def hasChildNodes(self): + return False + + def getType( self): + return SCRIPT + + def getPropertyValue( self, name ): + ret = None + try: + if name == "URI": + ret = self.provCtx.uriHelper.getScriptURI( + self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) ) + elif name == "Editable" and ENABLE_EDIT_DIALOG: + ret = not self.provCtx.sfa.isReadOnly( self.uri ) + + log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) ) + except Exception,e: + log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String()) + raise + + return ret + def setPropertyValue( self, name, value ): + log.isDebugLevel() and log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) ) + def getPropertySetInfo( self ): + log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertySetInfo called " ) + return None + + def getIntrospection( self ): + return None + + def invoke( self, name, params, outparamindex, outparams ): + if name == "Editable": + servicename = "com.sun.star.awt.DialogProvider" + ctx = self.provCtx.scriptContext.getComponentContext() + dlgprov = ctx.ServiceManager.createInstanceWithContext( + servicename, ctx ) + + self.editor = dlgprov.createDialog( + "vnd.sun.star.script:" + + "ScriptBindingLibrary.MacroEditor?location=application") + + code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri)) + code = ensureSourceState( code ) + self.editor.getControl("EditorTextField").setText(code) + + self.editor.getControl("RunButton").setActionCommand("Run") + self.editor.getControl("RunButton").addActionListener(self) + self.editor.getControl("SaveButton").setActionCommand("Save") + self.editor.getControl("SaveButton").addActionListener(self) + + self.editor.execute() + + return None + + def actionPerformed( self, event ): + try: + if event.ActionCommand == "Run": + code = self.editor.getControl("EditorTextField").getText() + code = ensureSourceState( code ) + mod = imp.new_module("ooo_script_framework") + mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext + exec code in mod.__dict__ + values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None ) + if not values: + values = mod.__dict__.values() + + for i in values: + if isScript( i ): + i() + break + + elif event.ActionCommand == "Save": + toWrite = uno.ByteSequence( + str( + self.editor.getControl("EditorTextField").getText().encode( + sys.getdefaultencoding())) ) + copyUrl = self.uri + ".orig" + self.provCtx.sfa.move( self.uri, copyUrl ) + out = self.provCtx.sfa.openFileWrite( self.uri ) + out.writeBytes( toWrite ) + out.close() + self.provCtx.sfa.kill( copyUrl ) +# log.isDebugLevel() and log.debug("Save is not implemented yet") +# text = self.editor.getControl("EditorTextField").getText() +# log.isDebugLevel() and log.debug("Would save: " + text) + except Exception,e: + # TODO: add an error box here ! + log.error( lastException2String() ) + + + def setValue( self, name, value ): + return None + + def getValue( self, name ): + return None + + def hasMethod( self, name ): + return False + + def hasProperty( self, name ): + return False + + +#------------------------------------------------------- +class FileBrowseNode( unohelper.Base, XBrowseNode ): + def __init__( self, provCtx, uri , name ): + self.provCtx = provCtx + self.uri = uri + self.name = name + self.funcnames = None + + def getName( self ): + return self.name + + def getChildNodes(self): + ret = () + try: + self.funcnames = self.provCtx.getFuncsByUrl( self.uri ) + + scriptNodeList = [] + for i in self.funcnames: + scriptNodeList.append( + ScriptBrowseNode( + self.provCtx, self.uri, self.name, i )) + ret = tuple( scriptNodeList ) + log.isDebugLevel() and log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri ) + except Exception, e: + text = lastException2String() + log.error( "Error while evaluating " + self.uri + ":" + text ) + raise + return ret + + def hasChildNodes(self): + try: + return len(self.getChildNodes()) > 0 + except Exception, e: + return False + + def getType( self): + return CONTAINER + + + +class DirBrowseNode( unohelper.Base, XBrowseNode ): + def __init__( self, provCtx, name, rootUrl ): + self.provCtx = provCtx + self.name = name + self.rootUrl = rootUrl + + def getName( self ): + return self.name + + def getChildNodes( self ): + try: + log.isDebugLevel() and log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl ) + contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True ) + browseNodeList = [] + for i in contents: + if i.endswith( ".py" ): + log.isDebugLevel() and log.debug( "adding filenode " + i ) + browseNodeList.append( + FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) ) + elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"): + log.isDebugLevel() and log.debug( "adding DirBrowseNode " + i ) + browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i)) + return tuple( browseNodeList ) + except Exception, e: + text = lastException2String() + log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl) + log.error( text) + return () + + def hasChildNodes( self ): + return True + + def getType( self ): + return CONTAINER + + def getScript( self, uri ): + log.debug( "DirBrowseNode getScript " + uri + " invoked" ) + raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 ) + + +class ManifestHandler( XDocumentHandler, unohelper.Base ): + def __init__( self, rootUrl ): + self.rootUrl = rootUrl + + def startDocument( self ): + self.urlList = [] + + def endDocument( self ): + pass + + def startElement( self , name, attlist): + if name == "manifest:file-entry": + if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script": + self.urlList.append( + self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) ) + + def endElement( self, name ): + pass + + def characters ( self, chars ): + pass + + def ignoreableWhitespace( self, chars ): + pass + + def setDocumentLocator( self, locator ): + pass + +def isPyFileInPath( sfa, path ): + ret = False + contents = sfa.getFolderContents( path, True ) + for i in contents: + if sfa.isFolder(i): + ret = isPyFileInPath(sfa,i) + else: + if i.endswith(".py"): + ret = True + if ret: + break + return ret + +# extracts META-INF directory from +def getPathesFromPackage( rootUrl, sfa ): + ret = () + try: + fileUrl = rootUrl + "/META-INF/manifest.xml" + inputStream = sfa.openFileRead( fileUrl ) + parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" ) + handler = ManifestHandler( rootUrl ) + parser.setDocumentHandler( handler ) + parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) ) + for i in tuple(handler.urlList): + if not isPyFileInPath( sfa, i ): + handler.urlList.remove(i) + ret = tuple( handler.urlList ) + except UnoException, e: + text = lastException2String() + log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +text ) + pass + return ret + + +class Package: + def __init__( self, pathes, transientPathElement ): + self.pathes = pathes + self.transientPathElement = transientPathElement + +class DummyInteractionHandler( unohelper.Base, XInteractionHandler ): + def __init__( self ): + pass + def handle( self, event): + log.isDebugLevel() and log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) ) + +class DummyProgressHandler( unohelper.Base, XProgressHandler ): + def __init__( self ): + pass + + def push( self,status ): + log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) ) + def update( self,status ): + log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) ) + def pop( self ): + log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) ) + +class CommandEnvironment(unohelper.Base, XCommandEnvironment): + def __init__( self ): + self.progressHandler = DummyProgressHandler() + self.interactionHandler = DummyInteractionHandler() + def getInteractionHandler( self ): + return self.interactionHandler + def getProgressHandler( self ): + return self.progressHandler + +#maybe useful for debugging purposes +#class ModifyListener( unohelper.Base, XModifyListener ): +# def __init__( self ): +# pass +# def modified( self, event ): +# log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.modified " + str( event ) ) +# def disposing( self, event ): +# log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.disposing " + str( event ) ) + +def mapStorageType2PackageContext( storageType ): + ret = storageType + if( storageType == "share:uno_packages" ): + ret = "shared" + if( storageType == "user:uno_packages" ): + ret = "user" + return ret + +def getPackageName2PathMap( sfa, storageType ): + ret = {} + packageManagerFactory = uno.getComponentContext().getValueByName( + "/singletons/com.sun.star.deployment.thePackageManagerFactory" ) + packageManager = packageManagerFactory.getPackageManager( + mapStorageType2PackageContext(storageType)) +# packageManager.addModifyListener( ModifyListener() ) + log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap start getDeployedPackages" ) + packages = packageManager.getDeployedPackages( + packageManager.createAbortChannel(), CommandEnvironment( ) ) + log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages))+")" ) + + for i in packages: + log.isDebugLevel() and log.debug( "inspecting package " + i.Name + "("+i.Identifier.Value+")" ) + transientPathElement = penultimateElement( i.URL ) + j = expandUri( i.URL ) + pathes = getPathesFromPackage( j, sfa ) + if len( pathes ) > 0: + # map package name to url, we need this later + log.isErrorLevel() and log.error( "adding Package " + transientPathElement + " " + str( pathes ) ) + ret[ lastElement( j ) ] = Package( pathes, transientPathElement ) + return ret + +def penultimateElement( aStr ): + lastSlash = aStr.rindex("/") + penultimateSlash = aStr.rindex("/",0,lastSlash-1) + return aStr[ penultimateSlash+1:lastSlash ] + +def lastElement( aStr): + return aStr[ aStr.rfind( "/" )+1:len(aStr)] + +class PackageBrowseNode( unohelper.Base, XBrowseNode ): + def __init__( self, provCtx, name, rootUrl ): + self.provCtx = provCtx + self.name = name + self.rootUrl = rootUrl + + def getName( self ): + return self.name + + def getChildNodes( self ): + items = self.provCtx.mapPackageName2Path.items() + browseNodeList = [] + for i in items: + if len( i[1].pathes ) == 1: + browseNodeList.append( + DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] )) + else: + for j in i[1].pathes: + browseNodeList.append( + DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) ) + return tuple( browseNodeList ) + + def hasChildNodes( self ): + return len( self.mapPackageName2Path ) > 0 + + def getType( self ): + return CONTAINER + + def getScript( self, uri ): + log.debug( "DirBrowseNode getScript " + uri + " invoked" ) + raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 ) + + + + +class PythonScript( unohelper.Base, XScript ): + def __init__( self, func, mod ): + self.func = func + self.mod = mod + def invoke(self, args, out, outindex ): + log.isDebugLevel() and log.debug( "PythonScript.invoke " + str( args ) ) + try: + ret = self.func( *args ) + except UnoException,e: + # UNO Exception continue to fly ... + text = lastException2String() + complete = "Error during invoking function " + \ + str(self.func.__name__) + " in module " + \ + self.mod.__file__ + " (" + text + ")" + log.isDebugLevel() and log.debug( complete ) + # some people may beat me up for modifying the exception text, + # but otherwise office just shows + # the type name and message text with no more information, + # this is really bad for most users. + e.Message = e.Message + " (" + complete + ")" + raise + except Exception,e: + # General python exception are converted to uno RuntimeException + text = lastException2String() + complete = "Error during invoking function " + \ + str(self.func.__name__) + " in module " + \ + self.mod.__file__ + " (" + text + ")" + log.isDebugLevel() and log.debug( complete ) + raise RuntimeException( complete , self ) + log.isDebugLevel() and log.debug( "PythonScript.invoke ret = " + str( ret ) ) + return ret, (), () + +def expandUri( uri ): + if uri.startswith( "vnd.sun.star.expand:" ): + uri = uri.replace( "vnd.sun.star.expand:", "",1) + uri = uno.getComponentContext().getByName( + "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri ) + if uri.startswith( "file:" ): + uri = uno.absolutize("",uri) # necessary to get rid of .. in uri + return uri + +#-------------------------------------------------------------- +class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer): + def __init__( self, ctx, *args ): + if log.isDebugLevel(): + mystr = "" + for i in args: + if len(mystr) > 0: + mystr = mystr +"," + mystr = mystr + str(i) + log.debug( "Entering PythonScriptProvider.ctor" + mystr ) + + storageType = "" + if isinstance(args[0],unicode ): + storageType = args[0] + else: + storageType = args[0].SCRIPTING_DOC_URI + isPackage = storageType.endswith( ":uno_packages" ) + + try: +# urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext( +# "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx) + urlHelper = MyUriHelper( ctx, storageType ) + log.isDebugLevel() and log.debug( "got urlHelper " + str( urlHelper ) ) + + rootUrl = expandUri( urlHelper.getRootStorageURI() ) + log.isDebugLevel() and log.debug( storageType + " transformed to " + rootUrl ) + + ucbService = "com.sun.star.ucb.SimpleFileAccess" + sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx ) + if not sfa: + log.debug("PythonScriptProvider couldn't instantiate " +ucbService) + raise RuntimeException( + "PythonScriptProvider couldn't instantiate " +ucbService, self) + self.provCtx = ProviderContext( + storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), None ) ) + if isPackage: + mapPackageName2Path = getPackageName2PathMap( sfa, storageType ) + self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl ) + self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) + else: + self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) + + except Exception, e: + text = lastException2String() + log.debug( "PythonScriptProvider could not be instantiated because of : " + text ) + raise e + + def getName( self ): + return self.dirBrowseNode.getName() + + def getChildNodes( self ): + return self.dirBrowseNode.getChildNodes() + + def hasChildNodes( self ): + return self.dirBrowseNode.hasChildNodes() + + def getType( self ): + return self.dirBrowseNode.getType() + + def getScript( self, uri ): + log.debug( "DirBrowseNode getScript " + uri + " invoked" ) + + raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 ) + + def getScript( self, scriptUri ): + try: + log.isDebugLevel() and log.debug( "getScript " + scriptUri + " invoked") + + storageUri = self.provCtx.getStorageUrlFromPersistentUrl( + self.provCtx.uriHelper.getStorageURI(scriptUri) ); + log.isDebugLevel() and log.debug( "getScript: storageUri = " + storageUri) + fileUri = storageUri[0:storageUri.find( "$" )] + funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)] + + mod = self.provCtx.getModuleByUrl( fileUri ) + log.isDebugLevel() and log.debug( " got mod " + str(mod) ) + + func = mod.__dict__[ funcName ] + + log.isDebugLevel() and log.debug( "got func " + str( func ) ) + return PythonScript( func, mod ) + except Exception, e: + text = lastException2String() + log.error( text ) + raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 ) + + + # XServiceInfo + def getSupportedServices( self ): + return g_ImplementationHelper.getSupportedServices(g_implName) + + def supportsService( self, ServiceName ): + return g_ImplementationHelper.supportsService( g_implName, ServiceName ) + + def getImplementationName(self): + return g_implName + + def getByName( self, name ): + log.debug( "getByName called" + str( name )) + return None + + + def getElementNames( self ): + log.debug( "getElementNames called") + return () + + def hasByName( self, name ): + try: + log.debug( "hasByName called " + str( name )) + uri = expandUri(name) + ret = self.provCtx.isUrlInPackage( uri ) + log.debug( "hasByName " + uri + " " +str( ret ) ) + return ret + except Exception, e: + text = lastException2String() + log.debug( "Error in hasByName:" + text ) + return False + + def removeByName( self, name ): + log.debug( "removeByName called" + str( name )) + uri = expandUri( name ) + if self.provCtx.isUrlInPackage( uri ): + self.provCtx.removePackageByUrl( uri ) + else: + log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" ) + raise NoSuchElementException( uri + "is not in package" , self ) + log.debug( "removeByName called" + str( uri ) + " successful" ) + + def insertByName( self, name, value ): + log.debug( "insertByName called " + str( name ) + " " + str( value )) + uri = expandUri( name ) + if isPyFileInPath( self.provCtx.sfa, uri ): + self.provCtx.addPackageByUrl( uri ) + else: + # package is no python package ... + log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" ) + raise IllegalArgumentException( uri + " does not contain .py files", self, 1 ) + log.debug( "insertByName called " + str( uri ) + " successful" ) + + def replaceByName( self, name, value ): + log.debug( "replaceByName called " + str( name ) + " " + str( value )) + removeByName( name ) + insertByName( name ) + log.debug( "replaceByName called" + str( uri ) + " successful" ) + + def getElementType( self ): + log.debug( "getElementType called" ) + return uno.getTypeByName( "void" ) + + def hasElements( self ): + log.debug( "hasElements got called") + return False + +g_ImplementationHelper.addImplementation( \ + PythonScriptProvider,g_implName, \ + ("com.sun.star.script.provider.LanguageScriptProvider", + "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),) + + +log.debug( "pythonscript finished intializing" ) + diff --git a/scripting/source/runtimemgr/ScriptExecDialog.hrc b/scripting/source/runtimemgr/ScriptExecDialog.hrc new file mode 100644 index 000000000000..8b1a63df29f3 --- /dev/null +++ b/scripting/source/runtimemgr/ScriptExecDialog.hrc @@ -0,0 +1,28 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define DLG_SCRIPTEXEC 1000 diff --git a/scripting/source/runtimemgr/ScriptExecDialog.src b/scripting/source/runtimemgr/ScriptExecDialog.src new file mode 100644 index 000000000000..dbc7f7e88795 --- /dev/null +++ b/scripting/source/runtimemgr/ScriptExecDialog.src @@ -0,0 +1,36 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "ScriptExecDialog.hrc" + +QueryBox DLG_SCRIPTEXEC +{ + Buttons = WB_YES_NO ; + DefButton = WB_DEF_YES ; + Title = "Script execution" ; + Message = "You are about to execute a script. Do you want to execute this script?" ; +}; diff --git a/scripting/source/runtimemgr/ScriptNameResolverImpl.cxx b/scripting/source/runtimemgr/ScriptNameResolverImpl.cxx new file mode 100644 index 000000000000..48b960c6c9aa --- /dev/null +++ b/scripting/source/runtimemgr/ScriptNameResolverImpl.cxx @@ -0,0 +1,660 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <vector> +#include <stdlib.h> + +#include <cppuhelper/implementationentry.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/security/AccessControlException.hpp> + +#include <util/util.hxx> +#include <util/scriptingconstants.hxx> + +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp> +#include <drafts/com/sun/star/script/framework/security/XScriptSecurity.hpp> + +#include "ScriptNameResolverImpl.hxx" +#include "ScriptRuntimeManager.hxx" + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +namespace scripting_runtimemgr +{ + +const sal_Char* const LANGUAGE_TO_RESOLVE_ON[] = { "All" }; // should be configurable +OUString nrs_implName = OUString::createFromAscii( + "drafts.com.sun.star.script.framework.runtime.DefaultScriptNameResolver" ); +OUString nrs_serviceName = OUString::createFromAscii( + "drafts.com.sun.star.script.framework.runtime.DefaultScriptNameResolver" ); +Sequence< OUString > nrs_serviceNames = Sequence< OUString >( &nrs_serviceName, 1 ); + +const char* const SCRIPTSTORAGEMANAGER_SERVICE = + "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager"; + +extern ::rtl_StandardModuleCount s_moduleCount; + +// define storages to search +static ::std::vector< sal_Int32 >* m_pSearchIDs = NULL; + +//************************************************************************* +ScriptNameResolverImpl::ScriptNameResolverImpl( + const Reference< XComponentContext > & xContext ) : + m_xContext( xContext ) +{ + OSL_TRACE( "< ScriptNameResolverImpl ctor called >\n" ); + validateXRef( m_xContext, "ScriptNameResolverImpl::ScriptNameResolverImpl: invalid context" ); + m_xMultiComFac = m_xContext->getServiceManager(); + + validateXRef( m_xMultiComFac, "ScriptNameResolverImpl::ScriptNameResolverImpl: invalid XMultiComponentFactory " ); + + if( !m_pSearchIDs ) + { + osl::Guard< osl::Mutex > aGuard( m_mutex ); + if( !m_pSearchIDs ) + { + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + m_pSearchIDs = new ::std::vector< sal_Int32 >(); + m_pSearchIDs->push_back( scriptingConstantsPool.DOC_STORAGE_ID_NOT_SET ); + m_pSearchIDs->push_back( scriptingConstantsPool.USER_STORAGE_ID ); + m_pSearchIDs->push_back( scriptingConstantsPool.SHARED_STORAGE_ID ); + } + } + + s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt ); +} + +//************************************************************************* +ScriptNameResolverImpl::~ScriptNameResolverImpl() +{ + OSL_TRACE( "< ScriptNameResolverImpl dtor called >\n" ); + s_moduleCount.modCnt.release( &s_moduleCount.modCnt ); +} + +//************************************************************************* +Reference< storage::XScriptInfo > ScriptNameResolverImpl::resolve( +const ::rtl::OUString & scriptURI, Any& invocationCtx ) +throw ( lang::IllegalArgumentException, script::CannotConvertException, RuntimeException ) +{ + + Reference< storage::XScriptInfo > resolvedName; + Reference< beans::XPropertySet > xPropSetScriptingContext; + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + + OSL_TRACE( "ScriptNameResolverImpl::resolve: in resolve - start" ); + + if ( sal_False == ( invocationCtx >>= xPropSetScriptingContext ) ) + { + throw RuntimeException( OUSTR( + "ScriptNameResolverImpl::resolve : unable to get XScriptingContext from param" ), + Reference< XInterface > () ); + } + + Any any; + OUString docUri; + sal_Int32 filesysScriptStorageID = -1; + Reference < storage::XScriptStorageManager > xScriptStorageMgr; + sal_Int32 docSid; + try + { + any = xPropSetScriptingContext->getPropertyValue( + scriptingConstantsPool.DOC_URI ); + OSL_TRACE( "ScriptNameResolverImpl::resolve: in resolve - got anyUri" ); + if ( sal_False == ( any >>= docUri ) ) + { + throw RuntimeException( OUSTR( + "ScriptNameResolverImpl::resolve : unable to get doc Uri from xPropSetScriptingContext" ), + Reference< XInterface > () ); + } + any = xPropSetScriptingContext->getPropertyValue( + scriptingConstantsPool.DOC_STORAGE_ID ); + if ( sal_False == ( any >>= docSid ) ) + { + throw RuntimeException( OUSTR( + "ScriptNameResolverImpl::resolve : unable to get doc storage id from xPropSetScriptingContext" ), + Reference< XInterface > () ); + } + } + catch ( Exception & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : problem with getPropertyValue" ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( OUSTR( + "ScriptNameResolverImpl::resolve Unknown Exception caught - RuntimeException rethrown" ), + Reference< XInterface > () ); + } +#endif + + + ::rtl::OString docUriO( + ::rtl::OUStringToOString( docUri , RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( + "ScriptNameResolverImpl::resolve: *** >>> DOC URI: %s, doc sid is %d\n", + docUriO.pData->buffer, docSid ); + + + OSL_TRACE( "ScriptNameResolverImpl::resolve Starting..." ); + OUString docString = OUString::createFromAscii( "location=document" ); + OUString userString = OUString::createFromAscii( "location=user" ); + OUString shareString = OUString::createFromAscii( "location=share" ); + OUString filesysString = OUString::createFromAscii( "location=filesystem" ); + + // initialise vector with doc, user and share + + // m_pSearchIDs is initialised as follows, + // m_pSearchIDs [ 0 ] empty + // m_pSearchIDs [ 1 ] user storage id + // m_pSearchIDs [ 2 ] share " " + + ::std::vector< sal_Int32 > m_vSearchIDs = *m_pSearchIDs; + m_vSearchIDs[ 0 ] = docSid; + + if ( scriptURI.indexOf( docString ) != -1 ) + { + OSL_TRACE("Full resolution available, search document"); + // search in document + m_vSearchIDs.resize( 1 ); + } + else if ( scriptURI.indexOf( userString ) != -1 ) + { + OSL_TRACE("Full resolution available, search user"); + // search in user + m_vSearchIDs[ 0 ] = ( *m_pSearchIDs )[ 1 ]; + m_vSearchIDs.resize( 1 ); + } + else if ( scriptURI.indexOf( shareString ) != -1 ) + { + OSL_TRACE("Full resolution available, search share"); + // search in share + m_vSearchIDs[ 0 ] = ( *m_pSearchIDs )[ 2 ]; + m_vSearchIDs.resize( 1 ); + } + else if ( scriptURI.indexOf( filesysString ) != -1 ) + { + OSL_TRACE("Full resolution available, create & search filesystem"); + OUString filesysURL; + try + { + filesysURL = getFilesysURL( scriptURI ); + } + catch ( lang::IllegalArgumentException & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::resolve: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + Reference< XInterface > xInterface = m_xMultiComFac->createInstanceWithContext( + ::rtl::OUString::createFromAscii( + "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ); + validateXRef( xInterface, + "ScriptProvider::initialise: cannot get SimpleFileAccess Service\n" ); + Reference < ucb::XSimpleFileAccess > xSimpleFileAccess = Reference < + ucb::XSimpleFileAccess > ( xInterface, UNO_QUERY_THROW ); + + // do we need to encode this? hope not. + OSL_TRACE( ">>>> About to create storage for %s", + ::rtl::OUStringToOString( filesysURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + // ask storage manager to create storage + try + { + // need to get the ScriptStorageManager + Any a = m_xContext->getValueByName( + scriptingConstantsPool.SCRIPTSTORAGEMANAGER_SERVICE ); + if ( sal_False == ( a >>= xScriptStorageMgr ) ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::resolve: failed to get ScriptStorageManager" ); + throw RuntimeException( temp, Reference< XInterface >() ); + // need to throw + } + validateXRef( xScriptStorageMgr, "Cannot get ScriptStorageManager" ); + filesysScriptStorageID = + xScriptStorageMgr->createScriptStorageWithURI( + xSimpleFileAccess, filesysURL ); + OSL_TRACE( ">>>> Created storage %d - for %s ", + filesysScriptStorageID, ::rtl::OUStringToOString( + filesysURL, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + catch ( RuntimeException & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::resolve: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + m_vSearchIDs[ 0 ] = filesysScriptStorageID; + m_vSearchIDs.resize( 1 ); + } + else + { + OSL_TRACE("Only partial uri available, search doc, user & share"); + // is this illegal or do we search in a default way + // if we get to here a uri has been passed in that has: + // a) not got a location specified + // b) an illegal location + + // detect illegal location + if ( scriptURI.indexOf( OUString::createFromAscii( "location=" ) ) != -1 ) + { + OSL_TRACE( + "ScriptNameResolver::resolve, throwing IllegalArgException" ); + throw lang::IllegalArgumentException( + OUSTR( "invalid URI: " ).concat( scriptURI ), + Reference < XInterface > (), 1 ); + + } + // leave vSearchIDs take care of the search... + } + + ::std::vector< sal_Int32 >::const_iterator iter; + ::std::vector< sal_Int32 >::const_iterator iterEnd = m_vSearchIDs.end(); + + for ( iter = m_vSearchIDs.begin() ; iter != iterEnd; ++iter ) + { + try + { + OSL_TRACE( "** about to resolve from storage using id %d from vector of size %d", + *iter, m_vSearchIDs.size() ); + if ( ( resolvedName = resolveURIFromStorageID( *iter, docUri, scriptURI ) ).is() ) + { + OSL_TRACE( "found match in uri from storage %d", *iter ); + xPropSetScriptingContext->setPropertyValue( + scriptingConstantsPool.RESOLVED_STORAGE_ID, makeAny(*iter) ); + break; + } + + } + catch ( css::security::AccessControlException & e ) + { + // no execute permission + OSL_TRACE( "ScriptNameResolverImpl::resolve : AccessControlException " ); + continue; + } + catch ( beans::UnknownPropertyException & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : UnknownPropertyException" ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } + catch ( beans::PropertyVetoException & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : PropertyVetoException " ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } + catch ( lang::IllegalArgumentException & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : IllegalArgumentException " ); + throw lang::IllegalArgumentException( temp.concat( e.Message ), + Reference< XInterface > (), e.ArgumentPosition ); + } + catch ( lang::WrappedTargetException & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : WrappedTargetException " ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } + catch ( Exception & e ) + { + OSL_TRACE( + "Exception thrown by storage %d, failed to match uri: %s", + *iter, + ::rtl::OUStringToOString( e.Message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve : unknown exception" ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + OSL_TRACE( + "unknown exception thrown by storage %d, failed to match uri", + *iter ); + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolve Unknown exception caught - RuntimeException rethrown" ); + throw RuntimeException( temp, + Reference< XInterface > () ); + } +#endif + + } + if ( !resolvedName.is() ) + { + if( filesysScriptStorageID > 2 ) + { + // get the filesys storage and dispose of it + Reference< XInterface > xScriptStorage = + xScriptStorageMgr->getScriptStorage( filesysScriptStorageID ); + validateXRef( xScriptStorage, + "ScriptNameResolverImpl::getStorageInstance: cannot get Script Storage service" ); + Reference< storage::XScriptInfoAccess > xScriptInfoAccess = Reference< + storage::XScriptInfoAccess > ( xScriptStorage, UNO_QUERY_THROW ); + validateXRef( xScriptInfoAccess, + "ScriptNameResolverImpl::resolveURIFromStorageID: cannot get XScriptInfoAccess" ); + Sequence< Reference< storage::XScriptInfo > > results = + xScriptInfoAccess->getAllImplementations( ); + Reference < lang::XEventListener > xEL_ScriptStorageMgr = + Reference< lang::XEventListener > + ( xScriptStorageMgr ,UNO_QUERY_THROW ); + validateXRef( xEL_ScriptStorageMgr, "ScriptNameResolverImpl::resolve: can't get ScriptStorageManager XEventListener interface when trying to dispose of filesystem storage" ); + lang::EventObject event( results[ 0 ] ); + xEL_ScriptStorageMgr->disposing( event ); + } + throw lang::IllegalArgumentException( OUSTR( + "ScriptNameResolverImpl::resolve: no script found for uri=" ).concat( scriptURI ), + Reference< XInterface > (), 0 ); + } + return resolvedName; +} + +//************************************************************************* +OUString SAL_CALL +ScriptNameResolverImpl::getImplementationName( ) +throw( RuntimeException ) +{ + return nrs_implName; +} + +//************************************************************************* +sal_Bool SAL_CALL +ScriptNameResolverImpl::supportsService( const OUString& serviceName ) +throw( RuntimeException ) +{ + OUString const * pNames = nrs_serviceNames.getConstArray(); + for ( sal_Int32 nPos = nrs_serviceNames.getLength(); nPos--; ) + { + if ( serviceName.equals( pNames[ nPos ] ) ) + { + return sal_True; + } + } + return sal_False; +} + +//************************************************************************* + +Reference< storage::XScriptInfo > +ScriptNameResolverImpl::resolveURIFromStorageID +( sal_Int32 sid, const ::rtl::OUString & docURI, + const ::rtl::OUString& scriptURI ) +SAL_THROW ( ( lang::IllegalArgumentException, css::security::AccessControlException, RuntimeException ) ) +{ + Reference< storage::XScriptInfo > resolvedScriptInfo; + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + if ( sid == scriptingConstantsPool.DOC_STORAGE_ID_NOT_SET ) + { + OSL_TRACE( "@@@@ **** ScriptNameResolverImpl::resolve DOC_STORAGE_ID_NOT_SET" ); + return resolvedScriptInfo; + } + try + { + OUString permissionURI = docURI; + OUString filesysString = OUString::createFromAscii( "location=filesystem" ); + if ( scriptURI.indexOf( filesysString ) != -1 ) + { + // in the case of filesys scripts we're checking whether the + // location of the script, rather than the location of the document, + // has execute permission + try + { + permissionURI = getFilesysURL( scriptURI ); + } + catch ( lang::IllegalArgumentException & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::resolveFromURI: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + } + Reference< storage::XScriptInfoAccess > storage = getStorageInstance( sid, permissionURI ); + validateXRef( storage, + "ScriptNameResolverImpl::resolveURIFromStorageID: cannot get XScriptInfoAccess" ); + Sequence< Reference< storage::XScriptInfo > > results = + storage->getImplementations( scriptURI ); + + const sal_Int32 length = results.getLength(); + + if ( !length ) + { + return resolvedScriptInfo; + } + + OSL_TRACE( "ScriptNameResolverImpl::resolve Got some results..." ); + // if we get results, just return first in list, + // storage has already matched language, function name etc. if + // that information was in the uri + resolvedScriptInfo = results[ 0 ]; + } + catch ( css::security::AccessControlException & ace ) + { + OUString temp = OUSTR( + "ScriptRuntimeManager::resolveURIFromStorageID AccessControlException: " ); + throw css::security::AccessControlException( temp.concat( ace.Message ), + Reference< XInterface > (), + ace.LackingPermission ); + } + catch ( lang::IllegalArgumentException & iae ) + { + OUString temp = OUSTR( + "ScriptRuntimeManager::resolveURIFromStorageID IllegalArgumentException: " ); + throw lang::IllegalArgumentException( temp.concat( iae.Message ), + Reference< XInterface > (), + iae.ArgumentPosition ); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( + "ScriptRuntimeManager::resolveURIFromStorageID RuntimeException: " ); + throw RuntimeException( temp.concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( + "ScriptNameResolverImpl::resolveURIFromStorageID : Exception caught - RuntimeException rethrown" ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( OUSTR( + "ScriptNameResolverImpl::resolveURIFromStorageID Unknown exception caught - RuntimeException rethrown" ), + Reference< XInterface > () ); + } +#endif + return resolvedScriptInfo; +} +//************************************************************************* + +Reference< storage::XScriptInfoAccess > + +ScriptNameResolverImpl::getStorageInstance( sal_Int32 sid, +const ::rtl::OUString & permissionURI ) SAL_THROW ( ( RuntimeException, css::security::AccessControlException, lang::IllegalArgumentException ) ) +{ + Reference< storage::XScriptInfoAccess > xScriptInfoAccess; + try + { + Reference< XInterface > xInterface; + + Any a = m_xContext->getValueByName( + OUString::createFromAscii( SCRIPTSTORAGEMANAGER_SERVICE ) ); + if ( sal_False == ( a >>= xInterface ) ) + { + throw RuntimeException( + OUSTR( "ScriptNameResolverImpl::getStorageInstance: could not obtain ScriptStorageManager singleton" ), + Reference< XInterface >() ); + } + validateXRef( xInterface, + "ScriptNameResolverImpl::getStorageInstance: cannot get Storage service" ); + // check that we have permissions for this storage + Reference< dcsssf::security::XScriptSecurity > xScriptSecurity( xInterface, UNO_QUERY_THROW ); + validateXRef( xScriptSecurity, + "ScriptNameResolverImpl::getStorageInstance: cannot get Script Security service" ); + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + // if we dealing with a document storage (ie. not user or share + // we need to check the permission + if( ( sid != scriptingConstantsPool.USER_STORAGE_ID ) && + ( sid != scriptingConstantsPool.SHARED_STORAGE_ID ) ) + { + xScriptSecurity->checkPermission( permissionURI, + OUString::createFromAscii( "execute" ) ); + // if we get here, the checkPermission hasn't thrown an + // AccessControlException, ie. permission has been granted + OSL_TRACE( "ScriptNameResolverImpl::getStorageInstance: got execute permission for ID=%d", sid ); + } + Reference< storage::XScriptStorageManager > xScriptStorageManager( xInterface, UNO_QUERY_THROW ); + validateXRef( xScriptStorageManager, + "ScriptNameResolverImpl::getStorageInstance: cannot get Script Storage Manager service" ); + Reference< XInterface > xScriptStorage = + xScriptStorageManager->getScriptStorage( sid ); + validateXRef( xScriptStorage, + "ScriptNameResolverImpl::getStorageInstance: cannot get Script Storage service" ); + xScriptInfoAccess = Reference< + storage::XScriptInfoAccess > ( xScriptStorage, UNO_QUERY_THROW ); + } + catch ( lang::IllegalArgumentException & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " ); + throw lang::IllegalArgumentException( temp.concat( e.Message ), + Reference< XInterface >(), e.ArgumentPosition ); + } + catch ( css::security::AccessControlException & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: AccessControlException " ); + throw css::security::AccessControlException( temp.concat( e.Message ), Reference< XInterface >(), e.LackingPermission ); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " ); + throw RuntimeException( temp.concat( re.Message ), Reference< XInterface >() ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + return xScriptInfoAccess; +} +//************************************************************************* +OUString +ScriptNameResolverImpl::getFilesysURL( const OUString & scriptURI ) +throw( lang::IllegalArgumentException ) +{ + OUString filePath; + OUString fileName; + OUString filesysString = OUString::createFromAscii( "location=filesystem" ); + sal_Int32 locationPos = scriptURI.indexOf( filesysString ); + // expect location=filesys:file:///foo/bar/myscript.bsh etc + // except the file url at this point is encoded + // so we should be ok searching for the '&' + sal_Int32 filesysStrLen = filesysString.getLength() + 1; + sal_Int32 endOfLocn = scriptURI.indexOf( '&', locationPos ); + if (endOfLocn == -1 ) + { + filePath = scriptURI.copy( locationPos + filesysString.getLength() + 1 ); + } + else + { + filePath = scriptURI.copy( locationPos + filesysStrLen, + endOfLocn - locationPos - filesysStrLen ); + } + //file name shoul also be encoded so again ok to search for '&' + OUString functionKey = OUString::createFromAscii( "function=" ); + sal_Int32 functionKeyLength = functionKey.getLength(); + sal_Int32 functionNamePos = scriptURI.indexOf( functionKey ); + if ( functionNamePos > 0 ) + { + sal_Int32 endOfFn = scriptURI.indexOf( '&', functionNamePos ); + if ( endOfFn == -1 ) + { + fileName = scriptURI.copy( functionNamePos + functionKeyLength ); + } + else + { + fileName = scriptURI.copy( functionNamePos + functionKeyLength, + endOfFn - functionNamePos - functionKeyLength ); + } + } + else + { + // we need to throw + OUString temp = OUSTR( "ScriptNameResolverImpl::getFilesysURL: error getting the filesysURL" ); + throw lang::IllegalArgumentException( temp, Reference< XInterface >(), 0 ); + } + filePath+=fileName; + OSL_TRACE( "ScriptNameResolverImpl::getFilesysURL: filesys URL = %s", + ::rtl::OUStringToOString( filePath, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return filePath; +} +//************************************************************************* +Sequence<OUString> SAL_CALL +ScriptNameResolverImpl::getSupportedServiceNames( ) +throw( RuntimeException ) +{ + return nrs_serviceNames; +} + +//************************************************************************* +Reference< XInterface > SAL_CALL scriptnri_create( + Reference< XComponentContext > const & xComponentContext ) +SAL_THROW( ( Exception ) ) +{ + return ( cppu::OWeakObject * ) new ScriptNameResolverImpl( xComponentContext ); +} + +//************************************************************************* +Sequence< OUString > scriptnri_getSupportedServiceNames() SAL_THROW( () ) +{ + return nrs_serviceNames; +} + +//************************************************************************* +OUString scriptnri_getImplementationName() SAL_THROW( () ) +{ + return nrs_implName; +} +} // namespace scripting_runtimemgr diff --git a/scripting/source/runtimemgr/ScriptNameResolverImpl.hxx b/scripting/source/runtimemgr/ScriptNameResolverImpl.hxx new file mode 100644 index 000000000000..18c62bb65841 --- /dev/null +++ b/scripting/source/runtimemgr/ScriptNameResolverImpl.hxx @@ -0,0 +1,110 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +#ifndef _FRAMEWORK_SCRIPT_SCRIPTNAMERESOLVERIMPL_HXX_ +#define _FRAMEWORK_SCRIPT_SCRIPTNAMERESOLVERIMPL_HXX_ + +#include <cppuhelper/implbase1.hxx> // helper for XInterface, XTypeProvider etc. + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/script/CannotConvertException.hpp> +#include <com/sun/star/reflection/InvocationTargetException.hpp> + +#include <drafts/com/sun/star/script/framework/runtime/XScriptNameResolver.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfo.hpp> + +namespace scripting_runtimemgr +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +class ScriptNameResolverImpl : public + ::cppu::WeakImplHelper1 < dcsssf::runtime::XScriptNameResolver > +{ +public: + /********************************************** + ScriptNameResolverImpl Constructor + @param the current context + */ + ScriptNameResolverImpl( + const css::uno::Reference< css::uno::XComponentContext > & xContext ); + ~ScriptNameResolverImpl(); + + // XServiceInfo implementation + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw( css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw( css::uno::RuntimeException ); + + /********************************************** + resolve method + @param scriptURI this is the given ScriptURI + @param invocationCtx the invocation context contains the + documentStorageID and document reference for use in script name + resolving. On full name resolution it sets the resolvedScriptStorageID to + the actual storage location of the fully resolved script. May or may not * be the + same as the documentStorageID. + @exception CannotResolveScriptNameException + @exception IllegalArgumentException + @exception NullPointerException + @return the resolved XScriptURI + */ + css::uno::Reference < dcsssf::storage::XScriptInfo > SAL_CALL resolve( + const ::rtl::OUString & scriptURI, + css::uno::Any& invocationCtx ) + throw( css::script::CannotConvertException, css::lang::IllegalArgumentException, + css::uno::RuntimeException ); +private: + css::uno::Reference < dcsssf::storage::XScriptInfo > + resolveURIFromStorageID( sal_Int32 sid, const rtl::OUString & docURI, + const ::rtl::OUString & nameToResolve ) + SAL_THROW ( ( css::lang::IllegalArgumentException, css::uno::RuntimeException ) ); + css::uno::Reference< dcsssf::storage::XScriptInfoAccess > + getStorageInstance( sal_Int32 sid, const rtl::OUString & permissionURI) + SAL_THROW ( ( css::uno::RuntimeException ) ); + ::rtl::OUString + ScriptNameResolverImpl::getFilesysURL( const ::rtl::OUString & scriptURI ) + throw( css::lang::IllegalArgumentException ); + + /********************************************** + Reference< XComponentContext > m_xContext + to obtain other services if needed + */ + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMultiComFac; + ::osl::Mutex m_mutex; + +}; +} // scripting_runtimemgr + +#endif //_FRAMEWORK_SCRIPT_SCRIPTNAMERESOLVERIMPL_HXX_ diff --git a/scripting/source/runtimemgr/ScriptRuntimeManager.cxx b/scripting/source/runtimemgr/ScriptRuntimeManager.cxx new file mode 100755 index 000000000000..48f21367e762 --- /dev/null +++ b/scripting/source/runtimemgr/ScriptRuntimeManager.cxx @@ -0,0 +1,566 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#ifndef _VCL_MSGBOX_HXX +#include <vcl/msgbox.hxx> +#endif + +#include "ScriptExecDialog.hrc" + +#include <util/scriptingconstants.hxx> + +#include <cppuhelper/implementationentry.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/EventObject.hpp> + +#include "ScriptNameResolverImpl.hxx" +#include "ScriptRuntimeManager.hxx" +#include <util/util.hxx> +#include <util/scriptingconstants.hxx> + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +namespace scripting_runtimemgr +{ + +static OUString s_implName = ::rtl::OUString::createFromAscii( + "drafts.com.sun.star.script.framework.runtime.ScriptRuntimeManager" ); +static OUString s_serviceName = ::rtl::OUString::createFromAscii( + "drafts.com.sun.star.script.framework.runtime.ScriptRuntimeManager" ); +static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 ); + +::rtl_StandardModuleCount s_moduleCount = MODULE_COUNT_INIT; + +//************************************************************************* +// ScriptRuntimeManager Constructor +ScriptRuntimeManager::ScriptRuntimeManager( + const Reference< XComponentContext > & xContext ) : + m_xContext( xContext ) +{ + OSL_TRACE( "< ScriptRuntimeManager ctor called >\n" ); + validateXRef( m_xContext, + "ScriptRuntimeManager::ScriptRuntimeManager: invalid context" ); + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, + "ScriptRuntimeManager::ScriptRuntimeManager: cannot get ServiceManager" ); + s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt ); + // test + //scripting_securitymgr::ScriptSecurityManager ssm(xContext); +} + +//************************************************************************* +// ScriptRuntimeManager Destructor +ScriptRuntimeManager::~ScriptRuntimeManager() +{ + OSL_TRACE( "< ScriptRuntimeManager dtor called >\n" ); + s_moduleCount.modCnt.release( &s_moduleCount.modCnt ); +} + +//************************************************************************* +// Get the proper XScriptInvocation +Reference< runtime::XScriptInvocation > SAL_CALL ScriptRuntimeManager::getScriptRuntime( +const Reference< XInterface >& scriptInfo ) +throw( RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptRuntimeManager in getScriptRuntime\n" ); + + Reference< runtime::XScriptInvocation > xScriptInvocation; + + try + { + Reference< XInterface > xInterface; + + Reference< storage::XScriptInfo > sinfo = + Reference< storage::XScriptInfo >( scriptInfo, UNO_QUERY_THROW ); + + OUStringBuffer *buf = new OUStringBuffer(80); + buf->appendAscii("/singletons/drafts.com.sun.star.script.framework.runtime.theScriptRuntimeFor"); + buf->append(sinfo->getLanguage()); + + Any a = m_xContext->getValueByName(buf->makeStringAndClear()); + + if ( sal_False == ( a >>= xInterface ) ) + { + throw RuntimeException( + sinfo->getLanguage().concat( OUSTR( " runtime support is not installed for this language" ) ), + Reference< XInterface >() ); + } + validateXRef( xInterface, + "ScriptRuntimeManager::GetScriptRuntime: cannot get appropriate ScriptRuntime Service" + ); + xScriptInvocation = Reference< runtime::XScriptInvocation >( xInterface, UNO_QUERY_THROW ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::GetScriptRuntime: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + + return xScriptInvocation; +} + +//************************************************************************* +// Get the proper XScriptNameResolver +Reference< runtime::XScriptNameResolver > SAL_CALL +ScriptRuntimeManager::getScriptNameResolver() +throw( RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptRuntimeManager in getScriptNameResolver\n" ); + Reference< runtime::XScriptNameResolver > xScriptNameResolver; + + try + { + Reference< XInterface > xInterface = m_xMgr->createInstanceWithContext( + OUString::createFromAscii( + "drafts.com.sun.star.script.framework.runtime.DefaultScriptNameResolver" ), + m_xContext ); + validateXRef( xInterface, + "ScriptRuntimeManager::GetScriptRuntime: cannot get instance of DefaultScriptNameResolver" ); + xScriptNameResolver = Reference< runtime::XScriptNameResolver >( xInterface, UNO_QUERY_THROW ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::GetScriptNameResolver: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + return xScriptNameResolver; +} + +//************************************************************************* +// XScriptInvocation implementation +Any SAL_CALL ScriptRuntimeManager::invoke( + const ::rtl::OUString & scriptURI, + const Any& invocationCtx, const Sequence< Any >& aParams, + Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) + throw ( lang::IllegalArgumentException, script::CannotConvertException, + reflection::InvocationTargetException, RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptRuntimeManager in runtimemgr invoke\n" ); + + Any results; + scripting_constants::ScriptingConstantsPool& scriptingConstantsPool = + scripting_constants::ScriptingConstantsPool::instance(); + + // Initialise resolved context with invocation context, + // the resolved context (resolvedCtx will be modified by the + // resolve method to contain the storage where the script code is + // stored + Any resolvedCtx = invocationCtx; + + try + { + Reference< storage::XScriptInfo > resolvedScript = resolve( scriptURI, + resolvedCtx ); + validateXRef( resolvedScript, "ScriptRuntimeManager::invoke: No resolvedURI" ); + + Reference< beans::XPropertySet > xPropSetResolvedCtx; + if ( sal_False == ( resolvedCtx >>= xPropSetResolvedCtx ) ) + { + throw RuntimeException( OUSTR( + "ScriptRuntimeManager::invoke : unable to get XPropSetScriptingContext from param" ), + Reference< XInterface > () ); + } + + Any any = xPropSetResolvedCtx->getPropertyValue( + scriptingConstantsPool.RESOLVED_STORAGE_ID ); + sal_Int32 resolvedSid; + if ( sal_False == ( any >>= resolvedSid ) ) + { + throw RuntimeException( OUSTR( + "ScriptRuntimeManager::invoke : unable to get resolved storage id from xPropSetResolvedCtx" ), + Reference< XInterface > () ); + } + + OSL_TRACE("Storage sid is: %d\n", resolvedSid); + + // modifying the XPropertySet on the resolved Context to contain the + // full script info + Any aResolvedScript; + aResolvedScript <<= resolvedScript; + + xPropSetResolvedCtx->setPropertyValue( scriptingConstantsPool.SCRIPT_INFO, + aResolvedScript ); + + Reference< runtime::XScriptInvocation > xScriptInvocation = + getScriptRuntime( resolvedScript ); + validateXRef( xScriptInvocation, + "ScriptRuntimeManager::invoke: cannot get instance of language specific runtime." ); + + // the scriptURI is currently passed to the language-dept runtime but + // is not used (may be useful in the future?). All of the script info + // is contained as a property(SCRIPT_INFO) within the resolvedCtx + results = xScriptInvocation->invoke( scriptURI, resolvedCtx, aParams, + aOutParamIndex, aOutParam ); + + // need to dispose of filesystem storage + OUString filesysString = OUString::createFromAscii( + "location=filesystem" ); + if ( scriptURI.indexOf( filesysString ) != -1 ) + { + Any a = m_xContext->getValueByName( + scriptingConstantsPool.SCRIPTSTORAGEMANAGER_SERVICE ); + Reference < lang::XEventListener > xEL_ScriptStorageManager; + if ( sal_False == ( a >>= xEL_ScriptStorageManager ) ) + { + throw RuntimeException( OUSTR( "ScriptRuntimeManager::invoke: can't get ScriptStorageManager XEventListener interface when trying to dispose of filesystem storage" ), + Reference< XInterface > () ); + } + validateXRef( xEL_ScriptStorageManager, "Cannot get XEventListener from ScriptStorageManager" ); + lang::EventObject event(resolvedScript); + xEL_ScriptStorageManager->disposing( event ); + } + } + catch ( lang::IllegalArgumentException & iae ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke IllegalArgumentException: " ); + throw lang::IllegalArgumentException( temp.concat( iae.Message ), + Reference< XInterface > (), + iae.ArgumentPosition ); + } + catch ( script::CannotConvertException & cce ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke CannotConvertException: " ); + throw script::CannotConvertException( temp.concat( cce.Message ), + Reference< XInterface > (), + cce.DestinationTypeClass, cce.Reason, + cce.ArgumentIndex ); + } + catch ( reflection::InvocationTargetException & ite ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke InvocationTargetException: " ); + throw reflection::InvocationTargetException( temp.concat( ite.Message ), + Reference< XInterface > (), ite.TargetException ); + } + catch ( beans::UnknownPropertyException & e ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke UnknownPropertyException: " ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } + catch ( lang::WrappedTargetException & e ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke WrappedTargetException : " ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke RuntimeException: " ); + throw RuntimeException( temp.concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::invoke Exception: " ); + throw RuntimeException( temp.concat( e.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( OUSTR( "ScriptRuntimeManager::invoke UnknownException: " ), + Reference< XInterface > () ); + } +#endif + OSL_TRACE( "** ==> ScriptRuntimeManager returned from invoke: %s\n", ::rtl::OUStringToOString( results.getValueTypeName(), RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return results; +} + +//************************************************************************* +// XScriptNameResolver implementation +Reference< storage::XScriptInfo > SAL_CALL +ScriptRuntimeManager::resolve( const ::rtl::OUString& scriptURI, + Any& invocationCtx ) +throw( lang::IllegalArgumentException, script::CannotConvertException, RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptRuntimeManager in resolve\n" ); + Reference< storage::XScriptInfo > resolvedURI; + + Reference< runtime::XScriptNameResolver > xScriptNameResolver = getScriptNameResolver(); + validateXRef( xScriptNameResolver, + "ScriptRuntimeManager::resolve: No ScriptNameResolver" ); + + try + { + resolvedURI = xScriptNameResolver->resolve( scriptURI, invocationCtx ); + } + catch ( lang::IllegalArgumentException & iae ) + { + OUString temp = + OUSTR( "ScriptRuntimeManager::resolve IllegalArgumentException: " ); + throw lang::IllegalArgumentException( temp.concat( iae.Message ), + Reference< XInterface > (), + iae.ArgumentPosition ); + } + catch ( script::CannotConvertException & cce ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::resolve CannotConvertException: " ); + throw script::CannotConvertException( temp.concat( cce.Message ), + Reference< XInterface > (), + cce.DestinationTypeClass, cce.Reason, + cce.ArgumentIndex ); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( "ScriptRuntimeManager::resolve RuntimeException: " ); + throw RuntimeException( temp.concat( re.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( + OUSTR( "ScriptRuntimeManager::resolve UnknownException: " ), + Reference< XInterface > () ); + } +#endif + + return resolvedURI; +} + +//************************************************************************* +OUString SAL_CALL ScriptRuntimeManager::getImplementationName( ) +throw( RuntimeException ) +{ + return s_implName; +} + +//************************************************************************* +sal_Bool SAL_CALL ScriptRuntimeManager::supportsService( const OUString& serviceName ) +throw( RuntimeException ) +{ + OUString const * pNames = s_serviceNames.getConstArray(); + for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; ) + { + if ( serviceName.equals( pNames[ nPos ] ) ) + { + return sal_True; + } + } + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ScriptRuntimeManager::getSupportedServiceNames( ) +throw( RuntimeException ) +{ + return s_serviceNames; +} + +//************************************************************************* +static Reference< XInterface > SAL_CALL srm_create( + const Reference< XComponentContext > & xCompC ) +{ + return ( cppu::OWeakObject * ) new ScriptRuntimeManager( xCompC ); +} + +//************************************************************************* +static Sequence<OUString> srm_getSupportedServiceNames( ) +SAL_THROW( () ) +{ + return s_serviceNames; +} + +//************************************************************************* +static OUString srm_getImplementationName( ) +SAL_THROW( () ) +{ + return s_implName; +} + +//************************************************************************* +Reference< XInterface > SAL_CALL scriptnri_create( + Reference< XComponentContext > const & xComponentContext ) +SAL_THROW( ( Exception ) ); + +//************************************************************************* +Sequence< OUString > scriptnri_getSupportedServiceNames() SAL_THROW( () ); + +//************************************************************************* +OUString scriptnri_getImplementationName() SAL_THROW( () ); + +//******************** ScriptStorageMangaer defines *********************** +Reference< XInterface > SAL_CALL ssm_create( + Reference< XComponentContext > const & xComponentContext ) +SAL_THROW( ( Exception ) ); +//************************************************************************* +Sequence< OUString > ssm_getSupportedServiceNames() SAL_THROW( () ); +//************************************************************************* +OUString ssm_getImplementationName() SAL_THROW( () ); +//************************************************************************* + +//************ Script Provider defines ************************************ +Reference< XInterface > SAL_CALL sp_create( const Reference< XComponentContext > & xCompC ); +//******************** ScriptProvider defines *************************** +Sequence< OUString > sp_getSupportedServiceNames( ) SAL_THROW( () ); +//************************************************************************* +OUString sp_getImplementationName( ) SAL_THROW( () ); +//************************************************************************* + +//************ ScriptStorage defines ************************************** +Reference< XInterface > SAL_CALL ss_create( const Reference< XComponentContext > & xCompC ); +//******************** ScriptProvider defines *************************** +Sequence< OUString > ss_getSupportedServiceNames( ) SAL_THROW( () ); +//************************************************************************* +OUString ss_getImplementationName( ) SAL_THROW( () ); +//************************************************************************* + + +static struct cppu::ImplementationEntry s_entries [] = + { + { + srm_create, srm_getImplementationName, + srm_getSupportedServiceNames, cppu::createSingleComponentFactory, + &s_moduleCount.modCnt, 0 + }, + { + scriptnri_create, scriptnri_getImplementationName, + scriptnri_getSupportedServiceNames, cppu::createSingleComponentFactory, + &s_moduleCount.modCnt, 0 + }, + { + ssm_create, ssm_getImplementationName, + ssm_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { + ss_create, ss_getImplementationName, + ss_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { + sp_create, sp_getImplementationName, + sp_getSupportedServiceNames, cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; +} // Namespace + +//####################################################################################### +//#### EXPORTED ######################################################################### +//####################################################################################### + +/** + * Gives the environment this component belongs to. + */ +extern "C" +{ + void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, + uno_Environment ** ppEnv ) + { + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + /** + * This function creates an implementation section in the registry and another subkey + * + * for each supported service. + * @param pServiceManager the service manager + * @param pRegistryKey the registry key + */ + sal_Bool SAL_CALL component_writeInfo( lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + if (::cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, + ::scripting_runtimemgr::s_entries )) + { + try + { + // register RuntimeManager singleton + + registry::XRegistryKey * pKey = + reinterpret_cast< registry::XRegistryKey * >(pRegistryKey); + + Reference< registry::XRegistryKey > xKey( + pKey->createKey( + + OUSTR("drafts.com.sun.star.script.framework.runtime.ScriptRuntimeManager/UNO/SINGLETONS/drafts.com.sun.star.script.framework.runtime.theScriptRuntimeManager"))); + xKey->setStringValue( OUSTR("drafts.com.sun.star.script.framework.runtime.ScriptRuntimeManager") ); + + // ScriptStorage Mangaer singleton + + xKey = pKey->createKey( + OUSTR("drafts.com.sun.star.script.framework.storage.ScriptStorageManager/UNO/SINGLETONS/drafts.com.sun.star.script.framework.storage.theScriptStorageManager")); + xKey->setStringValue( OUSTR("drafts.com.sun.star.script.framework.storage.ScriptStorageManager") ); + // Singleton entries are not handled by the setup process + // below is the only alternative at the momement which + // is to programmatically do this. + + // "Java" Runtime singleton entry + + xKey = pKey->createKey( + OUSTR("com.sun.star.scripting.runtime.java.ScriptRuntimeForJava$_ScriptRuntimeForJava/UNO/SINGLETONS/drafts.com.sun.star.script.framework.runtime.theScriptRuntimeForJava")); + xKey->setStringValue( OUSTR("drafts.com.sun.star.script.framework.runtime.ScriptRuntimeForJava") ); + + // "JavaScript" Runtime singleton entry + + xKey = pKey->createKey( + OUSTR("com.sun.star.scripting.runtime.javascript.ScriptRuntimeForJavaScript$_ScriptRuntimeForJavaScript/UNO/SINGLETONS/drafts.com.sun.star.script.framework.runtime.theScriptRuntimeForJavaScript")); + xKey->setStringValue( OUSTR("drafts.com.sun.star.script.framework.runtime.ScriptRuntimeForJavaScript") ); + + // "BeanShell" Runtime singleton entry + + xKey = pKey->createKey( + OUSTR("com.sun.star.scripting.runtime.beanshell.ScriptRuntimeForBeanShell$_ScriptRuntimeForBeanShell/UNO/SINGLETONS/drafts.com.sun.star.script.framework.runtime.theScriptRuntimeForBeanShell")); + xKey->setStringValue( OUSTR("drafts.com.sun.star.script.framework.runtime.ScriptRuntimeForBeanShell") ); + + return sal_True; + } + catch (Exception & exc) + { + } + } + return sal_False; + } + + /** + * This function is called to get service factories for an implementation. + * + * @param pImplName name of implementation + * @param pServiceManager a service manager, need for component creation + * @param pRegistryKey the registry key for this component, need for persistent + * data + * @return a component factory + */ + void * SAL_CALL component_getFactory( const sal_Char * pImplName, + lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, + pRegistryKey, ::scripting_runtimemgr::s_entries ); + } +} diff --git a/scripting/source/runtimemgr/ScriptRuntimeManager.hxx b/scripting/source/runtimemgr/ScriptRuntimeManager.hxx new file mode 100644 index 000000000000..0351aedaa1cc --- /dev/null +++ b/scripting/source/runtimemgr/ScriptRuntimeManager.hxx @@ -0,0 +1,149 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + + +#ifndef _FRAMEWORK_SCRIPT_SCRIPTRUNTIMEMANAGER_HXX_ +#define _FRAMEWORK_SCRIPT_SCRIPTRUNTIMEMANAGER_HXX_ + +#include <osl/mutex.hxx> + +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/script/CannotConvertException.hpp> +#include <com/sun/star/reflection/InvocationTargetException.hpp> + +#include <drafts/com/sun/star/script/framework/runtime/XScriptInvocation.hpp> +#include <drafts/com/sun/star/script/framework/runtime/XScriptNameResolver.hpp> + +namespace scripting_runtimemgr +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +/** + * Class responsible for managing the various ScriptRuntime implementations. + */ +class ScriptRuntimeManager : public + ::cppu::WeakImplHelper3< dcsssf::runtime::XScriptInvocation, css::lang::XServiceInfo, + dcsssf::runtime::XScriptNameResolver > +{ +public: + explicit ScriptRuntimeManager( + const css::uno::Reference< css::uno::XComponentContext > & xContext ); + ~ScriptRuntimeManager(); + + + // XServiceInfo implementation + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw( css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw( css::uno::RuntimeException ); + + /** + * implements XScriptInvocation, invokes the script named in scriptURI + * (resolving it first, if necessary), with the args passed. + * + * @param scriptURI the URI, which may not be fully qualified, for the + * script to be invoked + * + ************************************************************* + Invoke + @param scriptUri script uri describing the script + @param invocationCtx + the invocation context contains the documentStorageID and document reference + for use in script name resolving + + @param aParams all parameters; pure, out params are undefined in sequence, + i.e., the value has to be ignored by the callee + @param aOutParamIndex out indices + @param aOutParam out parameters + + @returns + the value returned from the function being invoked + + @throws IllegalArgumentException + if there is no matching script name + + @throws CannotConvertException + if args do not match or cannot be converted the those + of the invokee + + @throws InvocationTargetException + if the running script throws an exception this information is captured and + rethrown as this exception type. + + */ + virtual css::uno::Any SAL_CALL invoke( + const ::rtl::OUString & scriptUri, + const css::uno::Any& invocationCtx, + const css::uno::Sequence< css::uno::Any >& aParams, + css::uno::Sequence< sal_Int16 >& aOutParamIndex, + css::uno::Sequence< css::uno::Any >& aOutParam ) + throw ( css::lang::IllegalArgumentException, + css::script::CannotConvertException, + css::reflection::InvocationTargetException, + css::uno::RuntimeException ); + + /** + * implements XScriptNameResolver, attempts to resolve the script URI + * passed in + * + * @param scriptURI the URI to be resolved + * @param invocationCtx the invocation context contains the + * documentStorageID and document reference for use in script name + * resolving. On full name resolution it sets the resolvedScriptStorageID to + * the actual storage location of the fully resolved script. May or may not * be the + same as the documentStorageID. + * @return the resolved URI + */ + virtual css::uno::Reference< dcsssf::storage::XScriptInfo > SAL_CALL resolve( + const ::rtl::OUString& scriptUri, + css::uno::Any& invocationCtx ) + throw( css::lang::IllegalArgumentException, css::script::CannotConvertException, + css::uno::RuntimeException ); + +private: + css::uno::Reference< dcsssf::runtime::XScriptInvocation > SAL_CALL getScriptRuntime( + const css::uno::Reference< css::uno::XInterface > & scriptInfo ) + throw( css::uno::RuntimeException ); + css::uno::Reference< dcsssf::runtime::XScriptNameResolver > SAL_CALL getScriptNameResolver() + throw( css::uno::RuntimeException ); + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMgr; + ::osl::Mutex m_mutex; +}; +} // scripting_runtimemgr + +#endif //_FRAMEWORK_SCRIPT_SCRIPTRUNTIMEMANAGER_HXX_ diff --git a/scripting/source/runtimemgr/StorageBridge.cxx b/scripting/source/runtimemgr/StorageBridge.cxx new file mode 100644 index 000000000000..d1915afba9e5 --- /dev/null +++ b/scripting/source/runtimemgr/StorageBridge.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp> + +#include "StorageBridge.hxx" +#include <util/util.hxx> + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +namespace scripting_runtimemgr +{ + +const char* const SCRIPTIMPLACCESS_SERVICE = + "drafts.com.sun.star.script.framework.storage.StorageProxy"; +const char* const SCRIPTSTORAGEMANAGER_SERVICE = + "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager"; +const int STORAGEID = 0; +const int STORAGEPROXY = 0; + + +//************************************************************************* +// StorageBridge Constructor +StorageBridge::StorageBridge( const Reference< XComponentContext >& xContext, + sal_Int32 sid ) : m_xContext( xContext ), m_sid( sid ) +{ + validateXRef( m_xContext, "StorageBridge::StorageBridge: invalid context" ); + try + { + initStorage(); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( "StorageBridge::StorageBridge(salIn32&): " ); + throw RuntimeException( temp.concat( re.Message ), Reference< XInterface >() ); + } +} + +//************************************************************************* +void +StorageBridge::initStorage() throw ( ::com::sun::star::uno::RuntimeException ) +{ + try + { + Reference< lang::XMultiComponentFactory > xMultiComFac = + m_xContext->getServiceManager(); + validateXRef( xMultiComFac, + "StorageBridge::StorageBridge: cannot get multicomponentfactory from multiservice factory" ); + Reference< XInterface > temp; + + Any a = m_xContext->getValueByName( + OUString::createFromAscii( SCRIPTSTORAGEMANAGER_SERVICE ) ); + if ( sal_False == ( a >>= temp ) ) + { + throw RuntimeException( + OUSTR( "StorageBridge::StorageBridge: could not obtain ScriptStorageManager singleton" ), + Reference< XInterface >() ); + } + validateXRef( temp, + "StorageBridge::StorageBridge: cannot get Storage service" ); + Reference< storage::XScriptStorageManager > xScriptStorageManager( temp, UNO_QUERY_THROW ); + validateXRef( xScriptStorageManager, + "StorageBridge::StorageBridge: cannot get Script Storage Manager service" ); + Reference< XInterface > xScriptStorage = + xScriptStorageManager->getScriptStorage( m_sid ); + validateXRef( xScriptStorage, + "StorageBridge::StorageBridge: cannot get Script Storage service" ); + m_xScriptInfoAccess = + Reference< storage::XScriptInfoAccess > ( xScriptStorage, UNO_QUERY_THROW ); + } + catch ( RuntimeException & re ) + { + OUString temp = OUSTR( "StorageBridge::StorageBridge: " ); + throw RuntimeException( temp.concat( re.Message ), Reference< XInterface >() ); + } + catch ( Exception & e ) + { + OUString temp = OUSTR( "StorageBridge::StorageBridge: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } +} +//************************************************************************* +Sequence< ::rtl::OUString > +StorageBridge::getScriptLogicalNames() +throw ( lang::IllegalArgumentException, + RuntimeException ) +{ + OSL_TRACE( "In StorageBridge getScriptLogicalNames...\n" ); + Sequence < ::rtl::OUString > results; + try + { + results = m_xScriptInfoAccess->getScriptLogicalNames(); + } + catch ( Exception e ) + { + OUString temp = OUSTR( "StorageBridge::getScriptLogicalNames: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + return results; +} + +//************************************************************************* +Sequence < Reference< storage::XScriptInfo > > +StorageBridge::getImplementations( const ::rtl::OUString& queryURI ) +throw ( lang::IllegalArgumentException, RuntimeException ) +{ + OSL_TRACE( "In StorageBridge getImplementations...\n" ); + Sequence < Reference< storage::XScriptInfo > > results; + try + { + results = m_xScriptInfoAccess->getImplementations( queryURI ); + } + catch ( Exception e ) + { + OUString temp = OUSTR( "StorageBridge::getImplementations: " ); + throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() ); + } + return results; +} +}// namespace diff --git a/scripting/source/runtimemgr/StorageBridge.hxx b/scripting/source/runtimemgr/StorageBridge.hxx new file mode 100644 index 000000000000..2130fe3d2eea --- /dev/null +++ b/scripting/source/runtimemgr/StorageBridge.hxx @@ -0,0 +1,85 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + + +#ifndef _FRAMEWORK_SCRIPT_STORAGEBRIDGE_HXX_ +#define _FRAMEWORK_SCRIPT_STORAGEBRIDGE_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> +#include "StorageBridgeFactory.hxx" + +namespace scripting_runtimemgr +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +class StorageBridge : public ::cppu::WeakImplHelper1< dcsssf::storage::XScriptInfoAccess > +{ + friend class StorageBridgeFactory; +public: + //XScriptInfoAccess + //========================================================================= + /** + * Get the implementations for a given URI + * + * @param queryURI + * The URI to get the implementations for + * + * @return XScriptURI + * The URIs of the implementations + */ + virtual css::uno::Sequence< css::uno::Reference< dcsssf::storage::XScriptInfo > > + SAL_CALL getImplementations( + const ::rtl::OUString& queryURI ) + throw ( css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + //========================================================================= + /** + * Get the all logical names stored in this storage + * + * @return sequence < ::rtl::OUString > + * The logical names + */ + virtual css::uno::Sequence< ::rtl::OUString > + SAL_CALL getScriptLogicalNames() + throw ( css::lang::IllegalArgumentException, css::uno::RuntimeException ); +private: + StorageBridge( const css::uno::Reference< css::uno::XComponentContext >& xContext, + sal_Int32 sid ); + + void initStorage() throw ( css::uno::RuntimeException ); + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< dcsssf::storage::XScriptInfoAccess > m_xScriptInfoAccess; + sal_Int32 m_sid; +}; +} + +#endif //_COM_SUN_STAR_SCRIPTING_STORAGEBRIDGE_HXX_ diff --git a/scripting/source/runtimemgr/StorageBridgeFactory.cxx b/scripting/source/runtimemgr/StorageBridgeFactory.cxx new file mode 100644 index 000000000000..d88bc66c1a0a --- /dev/null +++ b/scripting/source/runtimemgr/StorageBridgeFactory.cxx @@ -0,0 +1,69 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + + +#include "StorageBridgeFactory.hxx" + +#include "StorageBridge.hxx" + +using namespace ::drafts::com::sun::star::script::framework; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; + +namespace scripting_runtimemgr +{ + +//************************************************************************* +StorageBridgeFactory::StorageBridgeFactory( + const Reference< XComponentContext >& xContext ) : + m_xContext( xContext ) +{} + + + +//************************************************************************* +// StorageBridge is a bridge between us an storage, the StorageBridge implements the +// XScriptInfoAccess +// interface, it allows both the "real" storage and a java test storage component to be +// configured. +// @param location contains a url for the document. +// @returns a storage instance for the location "location". +// @see StorageBridge.cxx for flag "STORAGEPROXY", set to use java "test" component or +// use "real" storage. + +Reference< storage::XScriptInfoAccess > +StorageBridgeFactory::getStorageInstance( sal_Int32 sid ) +{ + + Reference< storage::XScriptInfoAccess > storage = new StorageBridge( m_xContext, + sid ) ; + return storage; +} +} //scripting_runtimemgr diff --git a/scripting/source/runtimemgr/StorageBridgeFactory.hxx b/scripting/source/runtimemgr/StorageBridgeFactory.hxx new file mode 100644 index 000000000000..382f705cf944 --- /dev/null +++ b/scripting/source/runtimemgr/StorageBridgeFactory.hxx @@ -0,0 +1,58 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + + +#ifndef _FRAMEWORK_SCRIPT_STORAGEBRIDGEFACTORY_HXX_ +#define _FRAMEWORK_SCRIPT_STORAGEBRIDGEFACTORY_HXX_ + +#include <rtl/ustring> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/Reference.hxx> + +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> + +namespace scripting_runtimemgr +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +class StorageBridgeFactory +{ + +public: + explicit StorageBridgeFactory( + const css::uno::Reference < css::uno::XComponentContext > & xContext ); + css::uno::Reference < dcsssf::storage::XScriptInfoAccess > + getStorageInstance( sal_Int32 sid ); +private: + StorageBridgeFactory(); // No definition for default ctor + css::uno::Reference< css::uno::XComponentContext > m_xContext; +}; +} // scripting_runtimemgr +#endif //_FRAMEWORK_SCRIPT_NAMERESOLVER_HXX_ diff --git a/scripting/source/runtimemgr/exports.dxp b/scripting/source/runtimemgr/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/scripting/source/runtimemgr/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/scripting/source/runtimemgr/makefile.mk b/scripting/source/runtimemgr/makefile.mk new file mode 100644 index 000000000000..d802fd240a2c --- /dev/null +++ b/scripting/source/runtimemgr/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= scripting +TARGET= runtimemgr +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=\ + $(SLO)$/ScriptNameResolverImpl.obj\ + $(SLO)$/ScriptRuntimeManager.obj \ + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/runtimemgr/runtimemgr.xml b/scripting/source/runtimemgr/runtimemgr.xml new file mode 100755 index 000000000000..d2bfeb26e736 --- /dev/null +++ b/scripting/source/runtimemgr/runtimemgr.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> ScriptRuntimeManager </module-name> + <component-description> + <author> Alexis Ledoux</author> + <name> drafts.com.sun.star.script.framework.ScriptRuntimeManager </name> + <description> + This component is part of the Scripting Framework +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="final"/> + <supported-service> drafts.com.sun.star.script.framework.ScriptRuntimeManager </supported-service> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XMultiComponentFactory </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.uno.XNamingService </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.lang.XMain </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.registry.XSimpleRegistry </type> + <type> com.sun.star.loader.XImplementationLoader </type> + <type> com.sun.star.registry.XImplementationRegistration </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.connection.XAcceptor </type> + <type> com.sun.star.connection.XConnector </type> + <type> com.sun.star.container.XHierarchicalNameAccess </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.io.XOutputStream </type> + <type> drafts.com.sun.star.script.framework.storage.XScriptInfoAccess </type> + <type> drafts.com.sun.star.script.framework.storage.XScriptStorageManager </type> + <type> drafts.com.sun.star.script.framework.runtime.XScriptInvocation </type> + <type> drafts.com.sun.star.script.framework.runtime.XScriptNameResolver </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper$(UDK_MAJOR)$(COM) </runtime-module-dependency> + <runtime-module-dependency> salhelper$(UDK_MAJOR)$(COM) </runtime-module-dependency> + <runtime-module-dependency> cppu$(UDK_MAJOR) </runtime-module-dependency> + <runtime-module-dependency> reg$(UDK_MAJOR) </runtime-module-dependency> + <runtime-module-dependency> store$(UDK_MAJOR) </runtime-module-dependency> + <runtime-module-dependency> sal$(UDK_MAJOR) </runtime-module-dependency> +</module-description> diff --git a/scripting/source/storage/ScriptData.hxx b/scripting/source/storage/ScriptData.hxx new file mode 100644 index 000000000000..925380021919 --- /dev/null +++ b/scripting/source/storage/ScriptData.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SCRIPTING_STORAGE_SCRIPTDATA_HXX_ +#define _SCRIPTING_STORAGE_SCRIPTDATA_HXX_ + +#include <vector> +#include <hash_map> + +#include <cppu/macros.hxx> +#include <rtl/ustring.hxx> + + + +namespace scripting_impl +{ + +typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > str_pair; +typedef ::std::vector< str_pair > props_vec; +typedef ::std::hash_map< ::rtl::OUString, props_vec, ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > strpairvec_map; +typedef ::std::hash_map< ::rtl::OUString, ::std::pair< ::rtl::OUString, + ::rtl::OUString >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > strpair_map; +typedef ::std::hash_map< ::rtl::OUString, ::std::pair< props_vec, strpairvec_map >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > filesets_map; + +struct ScriptData +{ + + inline ScriptData::ScriptData() SAL_THROW( () ) + : parcelURI() + , language() + , locales() + , functionname() + , logicalname() + , languagedepprops() + , filesets() + { + } + + inline ScriptData::ScriptData( const ::rtl::OUString __parcelURI, + const ::rtl::OUString& __language, + const strpair_map& __locales, + const ::rtl::OUString& __functionname, + const ::rtl::OUString& __logicalname, + const props_vec& __languagedepprops, + const filesets_map& __filesets ) SAL_THROW( () ) + : parcelURI( __parcelURI ) + , language( __language ) + , locales( __locales ) + , functionname( __functionname ) + , logicalname( __logicalname ) + , languagedepprops( __languagedepprops ) + , filesets( __filesets ) + { + } + + ::rtl::OUString parcelURI; + ::rtl::OUString language; + strpair_map locales; + ::rtl::OUString functionname; + ::rtl::OUString logicalname; + props_vec languagedepprops; + filesets_map filesets; +}; +} // namespace scripting_impl +#endif // _SCRIPTING_STORAGE_ScriptData_HXX_ + diff --git a/scripting/source/storage/ScriptElement.cxx b/scripting/source/storage/ScriptElement.cxx new file mode 100644 index 000000000000..335110118507 --- /dev/null +++ b/scripting/source/storage/ScriptElement.cxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include "ScriptElement.hxx" +#include <util/util.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +typedef ::std::vector < ::std::pair < ::rtl::OUString, bool > > dependencies_vec; +typedef ::std::vector < ::std::pair < ::rtl::OUString, ::rtl::OUString > > deliveries_vec; + +namespace scripting_impl +{ + +//************************************************************************* +/** + Construct a ScriptElement from a ScriptData object + + @param sII + the ScriptDataObject +*/ +ScriptElement::ScriptElement( ScriptData & sII ) : + XMLElement( OUSTR( "parcel" ) ), + m_sII( sII ) +{ + OSL_TRACE( "ScriptElement ctor called\n" ); + + addAttribute( OUSTR( "language" ), sII.language ); + addAttribute( OUSTR( "xmlns:parcel" ), OUSTR( "scripting.dtd" ) ); + XMLElement* xScriptElt = new XMLElement( OUSTR( "script" ) ); + xScriptElt->addAttribute( OUSTR( "language" ), sII.language ); + Reference < xml::sax::XAttributeList > xal( xScriptElt ); + addSubElement( xal ); + + strpair_map::const_iterator mp_it = sII.locales.begin(); + strpair_map::const_iterator mp_itend = sII.locales.end(); + + for( ; mp_it != mp_itend; ++mp_it ) + { + XMLElement* xel = new XMLElement( OUSTR( "locale" ) ); + xel->addAttribute( OUSTR( "lang" ), mp_it->first ); + + { + XMLElement* subxel = new XMLElement( OUSTR( "displayname" ) ); + subxel->addAttribute( OUSTR( "value" ), mp_it->second.first ); + Reference < xml::sax::XAttributeList > subxattl( subxel ); + xel->addSubElement( subxattl ); + } + { + XMLElement* subxel = new XMLElement( OUSTR( "description" ), + mp_it->second.second ); + Reference< xml::sax::XAttributeList > subxattl( subxel ); + xel->addSubElement( subxattl ); + } + + Reference < xml::sax::XAttributeList > xal( xel ); + xScriptElt->addSubElement( xal ); + } + + { + XMLElement* xel = new XMLElement( OUSTR( "functionname" ) ); + xel->addAttribute( OUSTR( "value" ), sII.functionname ); + Reference < xml::sax::XAttributeList > xal( xel ); + xScriptElt->addSubElement( xal ); + } + + { + XMLElement* xel = new XMLElement( OUSTR( "logicalname" ) ); + xel->addAttribute( OUSTR( "value" ), sII.logicalname ); + Reference < xml::sax::XAttributeList > xal( xel ); + xScriptElt->addSubElement( xal ); + } + + props_vec::const_iterator vp_it = sII.languagedepprops.begin(); + props_vec::const_iterator vp_itend = sII.languagedepprops.end(); + + if ( vp_it != vp_itend ) + { + XMLElement* xel = new XMLElement( OUSTR( "languagedepprops" ) ); + + for( ; vp_it != vp_itend ; ++vp_it ) + { + XMLElement* subxel = new XMLElement( OUSTR( "prop" ) ); + subxel->addAttribute( OUSTR( "name" ), vp_it->first ); + subxel->addAttribute( OUSTR( "value" ), vp_it->second ); + Reference < xml::sax::XAttributeList > subxattl( subxel ); + xel->addSubElement( subxattl ); + } + + Reference < xml::sax::XAttributeList > xal( xel ); + xScriptElt->addSubElement( xal ); + } + + filesets_map::const_iterator fm_it = sII.filesets.begin(); + filesets_map::const_iterator fm_itend = sII.filesets.end(); + + for( ; fm_it != fm_itend; ++fm_it ) + { + XMLElement* xel = new XMLElement( OUSTR( "fileset" ) ); + xel->addAttribute( OUSTR( "name" ), fm_it->first ); + + vp_it = fm_it->second.first.begin(); + vp_itend = fm_it->second.first.end(); + + for( ; vp_it != vp_itend; ++vp_it ) + { + XMLElement* subxel = new XMLElement( OUSTR( "prop" ) ); + subxel->addAttribute( OUSTR( "name" ), vp_it->first ); + subxel->addAttribute( OUSTR("value"), vp_it->second ); + Reference < xml::sax::XAttributeList > subxattl( subxel ); + xel->addSubElement( subxattl ); + } + + strpairvec_map::const_iterator sm_it = fm_it->second.second.begin(); + strpairvec_map::const_iterator sm_itend = fm_it->second.second.end(); + + if( sm_it != sm_itend ) + { + // was there a purpose for contstructing this + // XMLElement* subxel = new XMLElement( OUSTR( "file" ) ); + xel->addAttribute( OUSTR( "name" ), sm_it->first ); + + } + } +} + +//************************************************************************* +ScriptElement::~ScriptElement() SAL_THROW(()) +{ +} + +} // namespace scripting_impl diff --git a/scripting/source/storage/ScriptElement.hxx b/scripting/source/storage/ScriptElement.hxx new file mode 100644 index 000000000000..70c7ab5276ec --- /dev/null +++ b/scripting/source/storage/ScriptElement.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SCRIPT_FRAMEWORK_STORAGE_SCRIPT_ELEMENT_HXX_ +#define _SCRIPT_FRAMEWORK_STORAGE_SCRIPT_ELEMENT_HXX_ + +#include <osl/mutex.hxx> + +#include "ScriptData.hxx" + +#include "XMLElement.hxx" + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +class ScriptElement : public ::scripting_impl::XMLElement +{ +public: + /** + Construct a ScriptElement from a ScriptData object + + @param sII + the ScriptData Object + */ + explicit ScriptElement( ScriptData & sII ); + ~ScriptElement() SAL_THROW (()); + +private: + ScriptData m_sII; + +}; + +} + +#endif diff --git a/scripting/source/storage/ScriptInfo.cxx b/scripting/source/storage/ScriptInfo.cxx new file mode 100644 index 000000000000..bbe21f3546ec --- /dev/null +++ b/scripting/source/storage/ScriptInfo.cxx @@ -0,0 +1,373 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <cppuhelper/implementationentry.hxx> + +#include <hash_map> + +#include <osl/file.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp> + +#include <util/util.hxx> +#include "ScriptInfo.hxx" + +using namespace ::rtl; +using namespace com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; +using namespace ::drafts::com::sun::star::script::framework::storage; + +namespace scripting_impl +{ + +typedef ::std::hash_map < ::rtl::OUString, css::uno::Any, ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > PropertySet_hash; + +class PropertySetImpl : public ::cppu::WeakImplHelper1< css::beans::XPropertySet > +{ + +public: + + PropertySetImpl(); + ~PropertySetImpl(); + +// XPropertySet implementation + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw ( css::uno::RuntimeException ); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, + const css::uno::Any& aValue ) + throw ( css::beans::UnknownPropertyException, + css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + virtual css::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) + throw ( css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, + const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) + throw ( css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + virtual void SAL_CALL removePropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) + throw ( css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + virtual void SAL_CALL addVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) + throw ( css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + virtual void SAL_CALL removeVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) + throw ( css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, + css::uno::RuntimeException ); + +private: + friend class ScriptInfo; + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + void PropertySetImpl::privateSetPropertyValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) + throw ( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + RuntimeException ); + + osl::Mutex m_mutex; + PropertySet_hash m_propertyMap; +}; + +PropertySetImpl::PropertySetImpl() +{ + OSL_TRACE( "<PropertySetImpl ctor called\n" ); +} + +PropertySetImpl::~PropertySetImpl() +{ + OSL_TRACE( "<PropertySetImpl dtor called\n>" ); +} + +Reference< beans::XPropertySetInfo > SAL_CALL PropertySetImpl::getPropertySetInfo( ) + throw ( RuntimeException ) +{ + return Reference< beans::XPropertySetInfo > (); // Not supported +} + +void SAL_CALL PropertySetImpl::setPropertyValue( const ::rtl::OUString& aPropertyName, + const Any& aValue ) + throw ( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + RuntimeException ) +{ + throw RuntimeException( + OUSTR( "PropertySetImpl::setPropertyValue: method not supported. Read-only PropertySet" ), + Reference< XInterface >() ); +} + +void PropertySetImpl::privateSetPropertyValue( const ::rtl::OUString& aPropertyName, + const Any& aValue ) + throw ( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + RuntimeException ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + m_propertyMap[ aPropertyName ] = aValue; +} + +//************************************************************************* +Any SAL_CALL PropertySetImpl::getPropertyValue( const ::rtl::OUString& PropertyName ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, RuntimeException ) +{ + if ( m_propertyMap.find( PropertyName ) == m_propertyMap.end() ) + { + throw RuntimeException( + + OUSTR( "PropertySetImpl::getPropertyValue: invalid PropertyName ").concat( + PropertyName), + Reference< XInterface >() ); + } + + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + Any returnValue = m_propertyMap[ PropertyName ]; + + return returnValue; +} + +//************************************************************************* +void SAL_CALL PropertySetImpl::addPropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const Reference< beans::XPropertyChangeListener >& xListener ) + throw ( beans::UnknownPropertyException, lang::WrappedTargetException, + RuntimeException ) +{ + throw RuntimeException( + OUSTR( "PropertySetImpl::addPropertyChangeListener: method not supported" ), + Reference< XInterface >() ); +} + +//************************************************************************* +void SAL_CALL PropertySetImpl::removePropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const Reference< beans::XPropertyChangeListener >& aListener ) + throw ( beans::UnknownPropertyException, lang::WrappedTargetException, + RuntimeException ) +{ + throw RuntimeException( + OUSTR( "PropertySetImpl::removePropertyChangeListener: method not supported" ), + Reference< XInterface >() ); +} + +//************************************************************************* +void SAL_CALL PropertySetImpl::addVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const Reference< beans::XVetoableChangeListener >& aListener ) + throw ( beans::UnknownPropertyException, lang::WrappedTargetException, + RuntimeException ) +{ + throw RuntimeException( + OUSTR( "PropertySetImpl::addVetoableChangeListener: method not supported" ), + Reference< XInterface >() ); +} + +//************************************************************************* +void SAL_CALL PropertySetImpl::removeVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const Reference< beans::XVetoableChangeListener >& aListener ) + throw ( beans::UnknownPropertyException, lang::WrappedTargetException, + RuntimeException ) +{ + throw RuntimeException( + OUSTR( "PropertySetImpl::removeVetoableChangeListener: method not supported" ), + Reference< XInterface >() ); +} + + +//************************************************************************* +ScriptInfo::ScriptInfo( const ScriptData & scriptData, sal_Int32 storageID ) + : m_scriptData( scriptData ), m_storageID( storageID ) +{ + OSL_TRACE( "< ++++++ ScriptInfo ctor called >\n" ); + OSL_TRACE( "< ++++++ parcelURI=%s>\n",::rtl::OUStringToOString(m_scriptData.parcelURI , RTL_TEXTENCODING_ASCII_US ).pData->buffer ); +} +//************************************************************************* +ScriptInfo::~ScriptInfo() +{ + OSL_TRACE( "< ScriptInfo dtor called >\n" ); +} +//************************************************************************* +OUString SAL_CALL ScriptInfo::getLogicalName( ) throw ( RuntimeException ) +{ + OSL_TRACE( "ScriptInfo::getLogicalName() " ); + return m_scriptData.logicalname; +} + +//************************************************************************* +OUString SAL_CALL ScriptInfo::getDescription( ) throw ( RuntimeException ) +{ + OUString rs_desc; + // TDB need to determine locale here, hardcoded at the moment + // to english + + OUString localeLang = OUString::createFromAscii( "en" ); + strpair_map::const_iterator str_it = + m_scriptData.locales.find( localeLang ); + + if( str_it == m_scriptData.locales.end() ) + { + OSL_TRACE( "No description set in meta-data" ); + return rs_desc; + } + rs_desc = str_it->second.second; + return rs_desc; +} + +//************************************************************************* +OUString SAL_CALL ScriptInfo::getLanguage( ) throw ( RuntimeException ) +{ + OSL_TRACE( "ScriptInfo::getLanguage() " ); + return m_scriptData.language; +} + +//************************************************************************* +OUString SAL_CALL ScriptInfo::getFunctionName( ) throw ( RuntimeException ) +{ + OSL_TRACE( "ScriptInfo::getFunctionName() " ); + return m_scriptData.functionname; +} + +//************************************************************************* +OUString SAL_CALL ScriptInfo::getParcelURI( ) throw ( RuntimeException ) +{ + return m_scriptData.parcelURI; +} + +//************************************************************************* +Reference< beans::XPropertySet > SAL_CALL ScriptInfo::getLanguageProperties( ) + throw ( RuntimeException ) +{ + PropertySetImpl* propSetImpl = new PropertySetImpl(); + Reference< beans::XPropertySet > xPropSet = propSetImpl; + + props_vec::const_iterator pv_it = m_scriptData.languagedepprops.begin(); + props_vec::const_iterator pv_itend = m_scriptData.languagedepprops.end(); + + for( ; pv_it != pv_itend; ++pv_it ) + { + try + { + propSetImpl->privateSetPropertyValue( pv_it->first, makeAny( pv_it->second ) ); + } + catch( Exception& e ) + { + OUString msg = OUSTR( + "ScriptInfo::getLanguage caught exception while setting property," ); + msg = msg.concat( OUSTR( " PropertryName: " ) ).concat( pv_it->first ); + msg = msg.concat( OUSTR( " \nException message is: " ) ); + msg = msg.concat( e.Message ); + throw RuntimeException( msg , Reference< XInterface >() ); + } + } + + return xPropSet; +} +//************************************************************************* +css::uno::Sequence< ::rtl::OUString > SAL_CALL ScriptInfo::getFileSetNames() +throw ( css::uno::RuntimeException ) +{ + OSL_TRACE("ScriptInfo::getFileSetNames"); + Sequence< OUString > results; + filesets_map::iterator fsm_it = m_scriptData.filesets.begin(); + filesets_map::iterator fsm_itend = m_scriptData.filesets.end(); + if( fsm_it == fsm_itend ) + { + OSL_TRACE( "ScriptInfo::getFileSetNames: no filesets" ); + return results; + } + results.realloc( m_scriptData.filesets.size() ); + for ( sal_Int32 count = 0; fsm_it != fsm_itend; ++fsm_it ) + { + OUString fileSetName = fsm_it->first; + OSL_TRACE( "ScriptInfo::getFileSetNames: adding name %s", + ::rtl::OUStringToOString( fileSetName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + results[ count++ ] = fileSetName; + } + return results; +} +//************************************************************************* +css::uno::Sequence< ::rtl::OUString > SAL_CALL +ScriptInfo::getFilesInFileSet( const ::rtl::OUString & fileSetName ) +throw ( css::uno::RuntimeException ) +{ + Sequence< OUString > results; + filesets_map::iterator fsm_it = m_scriptData.filesets.find( fileSetName ); + filesets_map::iterator fsm_itend = m_scriptData.filesets.end(); + if( fsm_it == fsm_itend ) + { + OSL_TRACE( "ScriptInfo::getFilesInFileSet: no fileset named %s", + ::rtl::OUStringToOString( fileSetName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return results; + } + + strpairvec_map files = fsm_it->second.second; + strpairvec_map::iterator spvm_it = files.begin(); + strpairvec_map::iterator spvm_itend = files.end(); + if( spvm_it == spvm_itend ) + { + OSL_TRACE( "ScriptInfo::getFilesInFileSet: no files in fileset %s", + ::rtl::OUStringToOString( fileSetName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return results; + } + results.realloc( files.size() ); + for( sal_Int32 count = 0; spvm_it != spvm_itend ; ++spvm_it ) + { + OUString fileName = spvm_it->first; + OSL_TRACE( "ScriptInfo::getFilesInFileSet: adding file %s", + ::rtl::OUStringToOString( fileName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + results[ count++ ] = fileName; + } + return results; +} +//************************************************************************* +} diff --git a/scripting/source/storage/ScriptInfo.hxx b/scripting/source/storage/ScriptInfo.hxx new file mode 100644 index 000000000000..a61126db8789 --- /dev/null +++ b/scripting/source/storage/ScriptInfo.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __SCRIPT_FRAMEWORK_STORAGE_SCRIPTINFO_HXX_ +#define __SCRIPT_FRAMEWORK_STORAGE_SCRIPTINFO_HXX_ + +#include <cppuhelper/implbase1.hxx> // helper for component factory + +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <drafts/com/sun/star/script/framework/storage/XScriptInfo.hpp> + +#include "ScriptData.hxx" + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +class ScriptInfo : public ::cppu::WeakImplHelper1< dcsssf::storage::XScriptInfo > +{ +public: + explicit ScriptInfo( const ScriptData & scriptData, sal_Int32 storageID ); + virtual ~ScriptInfo(); + + // XScriptInfo + virtual ::rtl::OUString SAL_CALL getLogicalName() + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getDescription() + throw ( css::uno::RuntimeException ) ; + virtual ::rtl::OUString SAL_CALL getLanguage() throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getFunctionName() + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getParcelURI() + throw ( css::uno::RuntimeException ); + virtual css::uno::Reference< css::beans::XPropertySet > SAL_CALL + getLanguageProperties() throw ( css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getFileSetNames() + throw ( css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL + getFilesInFileSet( const ::rtl::OUString & fileSetName ) + throw ( css::uno::RuntimeException ); + +private: + ScriptData m_scriptData; + sal_Int32 m_storageID; +}; + +} +#endif // define __SCRIPTING_STORAGE... diff --git a/scripting/source/storage/ScriptInfoImpl.hxx b/scripting/source/storage/ScriptInfoImpl.hxx new file mode 100644 index 000000000000..c02ee1b57db2 --- /dev/null +++ b/scripting/source/storage/ScriptInfoImpl.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SCRIPTING_STORAGE_SCRIPTINFOIMPL_HXX_ +#define _SCRIPTING_STORAGE_SCRIPTINFOIMPL_HXX_ + +#include <vector> +#include <map> + +#include <cppu/macros.hxx> +#include <rtl/ustring.hxx> + + +typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > str_pair; +typedef ::std::map< ::rtl::OUString, str_pair, + ::std::equal_to< ::rtl::OUString > > strpair_map; +typedef ::std::vector< str_pair > props_vec; +typedef ::std::map< ::rtl::OUString, ::std::pair< props_vec, strpair_map >, + ::std::equal_to< ::rtl::OUString > > filesets_map; + +namespace scripting_impl +{ + +struct ScriptInfoImpl +{ + + inline ScriptInfoImpl::ScriptInfoImpl() SAL_THROW( () ) + : parcelURI() + , language() + , locales() + , functionname() + , logicalname() + , languagedepprops() + , filesets() + { + } + + inline ScriptInfoImpl::ScriptInfoImpl( const ::rtl::OUString __parcelURI, + const ::rtl::OUString& __language, + const strpair_map& __locales, + const ::rtl::OUString& __functionname, + const ::rtl::OUString& __logicalname, + const langdepprops_vec& __languagedepprops, + const filesets_map& __filesets ) SAL_THROW( () ) + : parcelURI( __parcelURI ) + , language( __language ) + , locales( __locales ) + , functionname( __functionname ) + , logicalname( __logicalname ) + , languagedepprops( __languagedepprops ) + , filesets( __filesets ) + { + } + + ::rtl::OUString parcelURI; + ::rtl::OUString language; + strpair_map locales; + ::rtl::OUString functionname; + ::rtl::OUString logicalname; + props_vec languagedepprops; + filesets_map filesets; + +}; + + +} // namespace scripting_impl + +#endif // _SCRIPTING_STORAGE_SCRIPTINFOIMPL_HXX_ + diff --git a/scripting/source/storage/ScriptMetadataImporter.cxx b/scripting/source/storage/ScriptMetadataImporter.cxx new file mode 100644 index 000000000000..64dd87b2546b --- /dev/null +++ b/scripting/source/storage/ScriptMetadataImporter.cxx @@ -0,0 +1,532 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#ifdef _DEBUG +#include <stdio.h> +#endif + +#include "ScriptMetadataImporter.hxx" + +#include <osl/mutex.hxx> + +#include <com/sun/star/xml/sax/XParser.hpp> +#include <rtl/string.h> + + +#include <util/util.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace scripting_impl +{ +//************************************************************************* +ScriptMetadataImporter::ScriptMetadataImporter( + const Reference< XComponentContext > & xContext ) + : m_xContext( xContext ) +{ + OSL_TRACE( "< ScriptMetadataImporter ctor called >\n" ); + ms_localeDesc = new OUStringBuffer(); +} + +//************************************************************************* +ScriptMetadataImporter::~ScriptMetadataImporter() SAL_THROW( () ) +{ + OSL_TRACE( "< ScriptMetadataImporter dtor called >\n" ); + delete ms_localeDesc; +} + + +//************************************************************************* +void ScriptMetadataImporter::parseMetaData( + Reference< io::XInputStream > const & xInput, + const ::rtl::OUString & parcelURI, + InfoImpls_vec & io_ScriptDatas ) + throw ( xml::sax::SAXException, io::IOException, RuntimeException ) +{ + + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + mpv_ScriptDatas = &io_ScriptDatas; + mpv_ScriptDatas->clear(); + + //Set the placeholder for the parcel URI + ms_parcelURI = parcelURI; + + //Get the parser service + validateXRef( m_xContext, + "ScriptMetadataImporter::parseMetaData: No context available" ); + + Reference< lang::XMultiComponentFactory > xMgr = + m_xContext->getServiceManager(); + + validateXRef( xMgr, + "ScriptMetadataImporter::parseMetaData: No service manager available" ); + + Reference< XInterface > xInterface = xMgr->createInstanceWithContext( + OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ), m_xContext ); + + validateXRef( xInterface, "ScriptMetadataImporter::parseMetaData: cannot get SAX Parser" ); + Reference< xml::sax::XParser > xParser; + try + { + xParser.set( xInterface ,UNO_QUERY_THROW ); + } + catch (RuntimeException & re ) + { + OUString msg = OUString::createFromAscii( + "ScriptMetadata:Importer::parserMetaData cannot get XParser" ); + msg.concat( re.Message ); + throw RuntimeException( msg, Reference< XInterface > () ); + } + + // xxx todo: error handler, entity resolver omitted + // This class is the document handler for the parser + Reference< xml::sax::XDocumentHandler > t_smI( this ); + xParser->setDocumentHandler( t_smI ); + + //Set up the input for the parser, the XInputStream + xml::sax::InputSource source; + source.aInputStream = xInput; + source.sSystemId = OUSTR( "virtual file" ); + + OSL_TRACE( "ScriptMetadataImporter: Start the parser\n" ); + + try + { + xParser->parseStream( source ); + } + catch ( xml::sax::SAXException & saxe ) + { + OUString msg = OUString::createFromAscii( + "ScriptMetadata:Importer::parserMetaData SAXException" ); + msg.concat( saxe.Message ); + throw xml::sax::SAXException( msg, Reference< XInterface > (), + saxe.WrappedException ); + } + catch ( io::IOException & ioe ) + { + throw io::IOException( OUString::createFromAscii( + "ScriptMetadataImporter::parseMetaData IOException: " ) + ioe.Message, + Reference< XInterface > () ); + } + +#ifdef _DEBUG + catch ( ... ) + { + throw RuntimeException( OUString::createFromAscii( + "ScriptMetadataImporter::parseMetadata UnknownException: " ), + Reference< XInterface > () ); + } +#endif + + OSL_TRACE( "ScriptMetadataImporter: Parser finished\n "); + + OSL_TRACE( "ScriptMetadataImporter: vector size is %d\n", + mpv_ScriptDatas->size() ); +} + +//************************************************************************* +// XExtendedDocumentHandler impl +void ScriptMetadataImporter::startCDATA() + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: startCDATA()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::endCDATA() + throw ( RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: endDATA()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::comment( const ::rtl::OUString & sComment ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: comment()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::allowLineBreak() + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: allowLineBreak()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::unknown( const ::rtl::OUString & sString ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: unknown()\n" ); +} + +//************************************************************************* +// XDocumentHandler impl +void ScriptMetadataImporter::startDocument() + throw ( xml::sax::SAXException, RuntimeException ) +{ + // Ignore for now + OSL_TRACE( "ScriptMetadataImporter: startDocument()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::endDocument() + throw ( xml::sax::SAXException, RuntimeException ) +{ + // Ignore for now + OSL_TRACE( "ScriptMetadataImporter: endDocument()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::startElement( + const ::rtl::OUString& tagName, + const Reference< xml::sax::XAttributeList >& xAttribs ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + + OSL_TRACE( "Trace Message : ScriptMetadataImporter: startElement() %s\n", + ::rtl::OUStringToOString( tagName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + //Set the state of the state machine + setState( tagName ); + + //Processing the elements + switch( m_state ) + { + case SCRIPT: + m_ScriptData.parcelURI = ms_parcelURI; + m_ScriptData.language = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "language" )); + OSL_TRACE( "Trace Message: language is %s\n", + ::rtl::OUStringToOString( m_ScriptData.language, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case LOCALE: + ms_localeLang = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "lang" ) ); + OSL_TRACE( "Trace Message: Locale is %s\n", + ::rtl::OUStringToOString( ms_localeLang, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case DISPLAYNAME: + ms_localeDisName = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" )); + OSL_TRACE( "Trace Message: Displyaname is %s\n", + ::rtl::OUStringToOString( ms_localeDisName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case FUNCTIONNAME: + m_ScriptData.functionname = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ); + OSL_TRACE( "Trace Message: Functionname is %s\n", + ::rtl::OUStringToOString( m_ScriptData.functionname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case LOGICALNAME: + m_ScriptData.logicalname = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" )); +#ifdef _DEBUG + fprintf(stderr, "Trace Message: logicalname is %s\n", + ::rtl::OUStringToOString( m_ScriptData.logicalname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); +#endif + break; + case LANGDEPPROPS: + m_ScriptData.languagedepprops.push_back( + ::std::make_pair( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ) + )); + OSL_TRACE( "Trace Message: Langdepprops is %s\t%s\n", + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case FILESET: + ms_filesetname = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ); + OSL_TRACE( "Trace Message: filesetname is %s\n", + ::rtl::OUStringToOString(ms_filesetname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case FILESETPROPS: + mv_filesetprops.push_back( ::std::make_pair( + xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ) + )); + OSL_TRACE( "Trace Message: filesetprops is %s\t%s\n", + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + case FILES: + ms_filename = xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ); + OSL_TRACE( "Trace Message: filename is %s\n", + ::rtl::OUStringToOString( ms_filename, + RTL_TEXTENCODING_ASCII_US).pData->buffer ); + break; + case FILEPROPS: + /** + mm_files.insert( strpair_pair( ms_filename, + str_pair( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value") ) ) + ) + ); + */ + mv_fileprops.push_back(str_pair( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value") ) ) ); + OSL_TRACE( "Trace Message: fileprops is %s\t%s\n", + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "name" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( xAttribs->getValueByName( + ::rtl::OUString::createFromAscii( "value" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + break; + + // to prevent compiler warnings + case PARCEL: + case DESCRIPTION: + case LANGUAGEDEPPROPS: + break; + } +} + +//************************************************************************* +void ScriptMetadataImporter::endElement( const ::rtl::OUString & aName ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + + //The end tag of an element + OSL_TRACE( "ScriptMetadataImporter: endElement() %s\n", + ::rtl::OUStringToOString( aName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + //Set the state + setState( aName ); + + + switch ( m_state ) + { + case PARCEL: + break; + case SCRIPT: + // np adjust logicalName to be equal to function name + // as logical name concept has been removed + m_ScriptData.logicalname = m_ScriptData.functionname; + mpv_ScriptDatas->push_back( m_ScriptData ); + m_ScriptData = ScriptData(); + break; + case LOCALE: + m_ScriptData.locales[ ms_localeLang ] = ::std::make_pair( + ms_localeDisName, ms_localeDesc->makeStringAndClear().trim() ); + break; + case FILESET: + OSL_TRACE("adding fileset %s to filesets map", + ::rtl::OUStringToOString( ms_filesetname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + m_ScriptData.filesets[ ms_filesetname ] = ::std::make_pair( + mv_filesetprops, mm_files ); + mm_files.clear(); + mv_filesetprops.clear(); + break; + case FILES: + OSL_TRACE("adding files %s to files map", + ::rtl::OUStringToOString( ms_filename, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + mm_files[ ms_filename ] = mv_fileprops; + mv_fileprops.clear(); + break; + // + // to prevent compiler warnings + case DISPLAYNAME: + case DESCRIPTION: + case FUNCTIONNAME: + case LOGICALNAME: + case LANGUAGEDEPPROPS: + case LANGDEPPROPS: + case FILESETPROPS: + case FILEPROPS: + break; + } +} + +//************************************************************************* +void ScriptMetadataImporter::characters( const ::rtl::OUString & aChars ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: characters()\n"); + + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + switch ( m_state ) + { + case DESCRIPTION: + //Put description into the struct + ms_localeDesc->append(aChars); + break; + case PARCEL: + case SCRIPT: + case LOCALE: + case DISPLAYNAME: + case FUNCTIONNAME: + case LOGICALNAME: + case LANGUAGEDEPPROPS: + case LANGDEPPROPS: + case FILESETPROPS: + case FILEPROPS: + break; + } +} + +//************************************************************************* +void ScriptMetadataImporter::ignorableWhitespace( + const ::rtl::OUString & aWhitespaces ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: ignorableWhiteSpace()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::processingInstruction( + const ::rtl::OUString & aTarget, const ::rtl::OUString & aData ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: processingInstruction()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::setDocumentLocator( + const Reference< xml::sax::XLocator >& xLocator ) + throw ( xml::sax::SAXException, RuntimeException ) +{ + OSL_TRACE( "ScriptMetadataImporter: setDocumentLocator()\n" ); +} + +//************************************************************************* +void ScriptMetadataImporter::setState( const ::rtl::OUString & tagName ) +{ + //Set the state depending on the tag name of the current + //element the parser has arrived at + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "parcel" ) ) ) + { + //Parcel tag + m_state = PARCEL; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "script" ) ) ) + { + m_state = SCRIPT; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "locale" ) ) ) + { + m_state = LOCALE; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "displayname" ) ) ) + { + m_state = DISPLAYNAME; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "description" ) ) ) + { + m_state = DESCRIPTION; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "functionname" ) ) ) + { + m_state = FUNCTIONNAME; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "logicalname" ) ) ) + { + m_state = LOGICALNAME; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "languagedepprops" ) ) ) + { + m_state = LANGUAGEDEPPROPS; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "prop" ) ) ) + { + if( m_state == LANGUAGEDEPPROPS ) + { + m_state = LANGDEPPROPS; + } + else if( m_state == FILESET ) + { + m_state = FILESETPROPS; + } + else if( m_state == FILES ) + { + m_state = FILEPROPS; + } + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "fileset" ) ) ) + { + m_state = FILESET; + } + else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "file" ) ) ) + { + m_state = FILES; + } + else + { + //If there is a tag we don't know about, throw a exception (wobbler) :) + ::rtl::OUString str_sax = ::rtl::OUString::createFromAscii( "No Such Tag" ); + + OSL_TRACE( "ScriptMetadataImporter: No Such Tag: %s\n", + ::rtl::OUStringToOString( + tagName, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + throw xml::sax::SAXException( + str_sax, Reference< XInterface >(), Any() ); + } +} + +} diff --git a/scripting/source/storage/ScriptMetadataImporter.hxx b/scripting/source/storage/ScriptMetadataImporter.hxx new file mode 100644 index 000000000000..cb00833b7187 --- /dev/null +++ b/scripting/source/storage/ScriptMetadataImporter.hxx @@ -0,0 +1,251 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SCRIPTING_STORAGE_SCRIPTMETADATAIMPORTER_HXX_ +#define _SCRIPTING_STORAGE_SCRIPTMETADATAIMPORTER_HXX_ + +#include <vector> + +#include <rtl/ustring.h> +#include <rtl/ustrbuf.hxx> +#include <osl/mutex.hxx> +#include <cppuhelper/implbase1.hxx> // helper for component factory + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#include <com/sun/star/io/XInputStream.hpp> + +#include "ScriptData.hxx" + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +typedef ::std::vector< ScriptData > InfoImpls_vec; +typedef ::std::pair< ::rtl::OUString, ::std::pair< ::rtl::OUString, + ::rtl::OUString > > strpair_pair; + +/** + * Script Meta Data Importer + */ +class ScriptMetadataImporter : public + ::cppu::WeakImplHelper1< css::xml::sax::XExtendedDocumentHandler > +{ +public: + + /** + * This function will begin the parser and parse the meta data + * + * @param xInput The XInputStream for the parser which contains the XML + * @param parcelURI The parcel's URI in the document or the application + * + * @see css::io::XInputStream + */ + void parseMetaData( css::uno::Reference< css::io::XInputStream > + const & xInput, const ::rtl::OUString & parcelURI, + InfoImpls_vec & io_ScriptDatas ) + throw ( css::xml::sax::SAXException, css::io::IOException, + css::uno::RuntimeException ); + + /** + * Constructor for the meta-data parser + * + * @param XComponentContext + */ + explicit ScriptMetadataImporter( + const css::uno::Reference< css::uno::XComponentContext >& ); + + /** + * Destructor for the parser + */ + virtual ~ScriptMetadataImporter() SAL_THROW( () ); + + // XExtendedDocumentHandler impl + /** + * Function to handle the start of CDATA in XML + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + virtual void SAL_CALL startCDATA() + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle the end of CDATA in XML + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + virtual void SAL_CALL endCDATA() throw ( css::uno::RuntimeException ); + + /** + * Function to handle comments in XML + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + virtual void SAL_CALL comment( const ::rtl::OUString & sComment ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle line breaks in XML + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + virtual void SAL_CALL allowLineBreak() + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle unknowns in XML + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + virtual void SAL_CALL unknown( const ::rtl::OUString & sString ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle the start of XML document + * + * @see com::sun::star::xml::sax::XExtendedDocumentHandler + */ + // XDocumentHandler impl + virtual void SAL_CALL startDocument() + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle the end of the XML document + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL endDocument() + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle the start of an element + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL startElement( const ::rtl::OUString& aName, + const css::uno::Reference< css::xml::sax::XAttributeList > & xAttribs ) + throw ( css::xml::sax::SAXException, + css::uno::RuntimeException ); + + /** + * Function to handle the end of an element + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL endElement( const ::rtl::OUString & aName ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle characters in elements + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL characters( const ::rtl::OUString & aChars ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle whitespace + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString & aWhitespaces ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to handle XML processing instructions + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL processingInstruction( + const ::rtl::OUString & aTarget, const ::rtl::OUString & aData ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + /** + * Function to set the document locator + * + * @see com::sun::star::xml::sax::XDocumentHandler + */ + virtual void SAL_CALL setDocumentLocator( + const css::uno::Reference< css::xml::sax::XLocator >& xLocator ) + throw ( css::xml::sax::SAXException, css::uno::RuntimeException ); + + + +private: + + /** Vector contains the ScriptData structs */ + InfoImpls_vec* mpv_ScriptDatas; + + /** @internal */ + osl::Mutex m_mutex; + + /** @internal */ + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + /** Placeholder for the parcel URI */ + ::rtl::OUString ms_parcelURI; + + /** States for state machine during parsing */ + enum { PARCEL, SCRIPT, LOCALE, DISPLAYNAME, DESCRIPTION, FUNCTIONNAME, + LOGICALNAME, LANGUAGEDEPPROPS, LANGDEPPROPS, FILESET, FILESETPROPS, + FILES, FILEPROPS } m_state; + + /** Build up the struct during parsing the meta data */ + ScriptData m_ScriptData; + + /** @internal */ + ::rtl::OUString ms_localeLang; + ::rtl::OUString ms_localeDisName; + ::rtl::OUStringBuffer *ms_localeDesc; + + props_vec mv_filesetprops; + + ::rtl::OUString ms_filename; + ::rtl::OUString ms_filesetname; + + props_vec mv_fileprops; + + strpairvec_map mm_files; + + InfoImpls_vec mv_ScriptDatas; + + /** + * Helper function to set the state + * + * @param tagName + * The current tag being processed + */ + void setState(const ::rtl::OUString & tagName); +} +; // class ScriptMetadataImporter + +} + +#endif diff --git a/scripting/source/storage/ScriptSecurityManager.cxx b/scripting/source/storage/ScriptSecurityManager.cxx new file mode 100755 index 000000000000..3fde4e466974 --- /dev/null +++ b/scripting/source/storage/ScriptSecurityManager.cxx @@ -0,0 +1,605 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/WrappedTargetException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/security/AccessControlException.hpp> +#include <com/sun/star/security/RuntimePermission.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> +#include "ScriptSecurityManager.hxx" +#include <util/util.hxx> +#include <util/scriptingconstants.hxx> + + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +// is this in the utils? +const char* const SCRIPTSTORAGEMANAGER_SERVICE = + "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager"; + +namespace scripting_securitymgr +{ + +static OUString s_configProv = ::rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider"); + +static OUString s_configAccess = ::rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess"); + +static OUString s_configUpdate = ::rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationUpdateAccess"); + +static OUString s_securityDialog = ::rtl::OUString::createFromAscii( + "com.sun.star.script.framework.security.SecurityDialog"); + +static const int PERMISSION_NEVER = 0; +static const int PERMISSION_PATHLIST = 1; +static const int PERMISSION_ALWAYS = 2; + +static const int ALLOW_RUN = 1; +static const int ADD_TO_PATH = 2; + +//************************************************************************* +// ScriptSecurityManager Constructor +ScriptSecurityManager::ScriptSecurityManager( + const Reference< XComponentContext > & xContext ) throw ( RuntimeException ) + : m_xContext( xContext) +{ + OSL_TRACE( "< ScriptSecurityManager ctor called >\n" ); + validateXRef( m_xContext, + "ScriptSecurityManager::ScriptSecurityManager: invalid context" ); + + // get the service manager from the context + Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager(); + validateXRef( xMgr, + "ScriptSecurityManager::ScriptSecurityManager: cannot get ServiceManager" ); + + // create an instance of the ConfigurationProvider + Reference< XInterface > xInterface = xMgr->createInstanceWithContext( + s_configProv, m_xContext ); + validateXRef( xInterface, + "ScriptSecurityManager::ScriptSecurityManager: cannot get ConfigurationProvider" ); + // create an instance of the ConfigurationAccess for accessing the + // scripting security settings + m_xConfigProvFactory = Reference < lang::XMultiServiceFactory > ( xInterface, UNO_QUERY ); + validateXRef( m_xConfigProvFactory, + "ScriptSecurityManager::ScriptSecurityManager: cannot get XMultiServiceFactory interface from ConfigurationProvider" ); + +} + +void ScriptSecurityManager::addScriptStorage( rtl::OUString scriptStorageURL, + sal_Int32 storageID) +throw ( RuntimeException ) +{ + Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL ); + if ( ph_it != m_permissionSettings.end() ) + { + OSL_TRACE( "ScriptSecurityManager::addScriptStorage: already called for %s", + ::rtl::OUStringToOString( scriptStorageURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer); + return; + } + StoragePerm newPerm; + newPerm.scriptStorageURL=scriptStorageURL; + newPerm.storageID=storageID; + + // we err on the side of caution!! + newPerm.execPermission=sal_False; + + //need to check if storage has any scripts + try + { + /* need to replace this with something better, now logical names are + * gone + + Reference< XInterface > xInterface; + Any a = m_xContext->getValueByName( + OUString::createFromAscii( SCRIPTSTORAGEMANAGER_SERVICE ) ); + if ( sal_False == ( a >>= xInterface ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager::addScriptStorage: could not obtain ScriptStorageManager singleton" ), + Reference< XInterface >() ); + } + validateXRef( xInterface, + "ScriptSecurityManager::addScriptStorage: cannot get Storage service" ); + Reference< storage::XScriptStorageManager > xScriptStorageManager( + xInterface, UNO_QUERY_THROW ); + Reference< XInterface > xScriptStorage = + xScriptStorageManager->getScriptStorage( storageID ); + validateXRef( xScriptStorage, + "ScriptNameResolverImpl::getStorageInstance: cannot get Script Storage service" ); + Reference< storage::XScriptInfoAccess > xScriptInfoAccess = + Reference< storage::XScriptInfoAccess > ( xScriptStorage, + UNO_QUERY_THROW ); + Sequence< ::rtl::OUString > logicalNames = xScriptInfoAccess->getScriptLogicalNames(); + if( !logicalNames.getLength() ) // we have no logical names + { + return; + } */ + + // we have some scripts so read config & decide on that basis + // Setup flags: m_runMacroSetting, m_warning, m_confirmationRequired, + readConfiguration(); + } + catch ( RuntimeException & rte ) + { + OSL_TRACE( "ScriptSecurityManager::addScriptStorage: caught RuntimeException: %s", + ::rtl::OUStringToOString( rte.Message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer); + throw RuntimeException( + OUSTR( "ScriptSecurityManager::addScriptStorage: caught RuntimeException" ).concat( rte.Message ), + Reference< XInterface >() ); + } + + switch( m_runMacroSetting ) + { + case PERMISSION_NEVER: // never + { + OSL_TRACE("never run"); + break; + } + case PERMISSION_PATHLIST: // according to path list + { + OSL_TRACE("according to path"); + // check path + rtl::OUString path = scriptStorageURL.copy( 0, scriptStorageURL.lastIndexOf( '/' ) ); + OSL_TRACE( "no of elts in path list = %d", + (int)m_secureURL.getLength() ); + bool match = isSecureURL( path ); + if( match && ( m_warning == sal_True ) ) + { + OSL_TRACE("path match & warning dialog"); + int result = (int)executeStandardDialog(); + OSL_TRACE("result = %d", (int)result); + if ( (result&ALLOW_RUN) == ALLOW_RUN ) + { + newPerm.execPermission=sal_True; + } + break; + } + else if ( match ) + { + OSL_TRACE("path match & no warning dialog"); + newPerm.execPermission=sal_True; + break; + } + else if( m_confirmationRequired == sal_True ) + { + OSL_TRACE("no path match & confirmation dialog"); + int result = (int)executePathDialog( path ); + OSL_TRACE("result = %d", (int)result); + if ( (result&ALLOW_RUN) == ALLOW_RUN ) + { + newPerm.execPermission=sal_True; + } + if ( (result&ADD_TO_PATH) == ADD_TO_PATH ) + { + /* if checkbox clicked then need to add path to registry*/ + addToSecurePaths(path); + } + } + break; + } + case PERMISSION_ALWAYS: // always + if( m_warning == sal_True ) + { + OSL_TRACE("always & warning dialog"); + short result = executeStandardDialog(); + if ( (result&ALLOW_RUN) == ALLOW_RUN ) + { + newPerm.execPermission=sal_True; + } + } + else + { + OSL_TRACE("always & no warning dialog"); + newPerm.execPermission=sal_True; + } + break; + default: + // + throw RuntimeException( + OUSTR( "ScriptSecurityManager::addScriptStorage got invalid OfficeBasic setting"), + Reference< XInterface > ()); + } + + if ( newPerm.execPermission == sal_True ) + { + OSL_TRACE("setting exec permission to true for %s", + ::rtl::OUStringToOString( scriptStorageURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + else + { + OSL_TRACE("setting exec permission to false for %s", + ::rtl::OUStringToOString( scriptStorageURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + + m_permissionSettings[ scriptStorageURL ] = newPerm; +} + +bool ScriptSecurityManager::isSecureURL( const OUString & path ) +{ + bool match = false; + OSL_TRACE( "no of elts in path list = %d", + (int)m_secureURL.getLength() ); + OSL_TRACE("document path: %s", + ::rtl::OUStringToOString( path, + RTL_TEXTENCODING_ASCII_US ).pData->buffer); + int length = m_secureURL.getLength(); + for( int j = 0; j < length ; j++ ) + { + OSL_TRACE("path list element: %s", + ::rtl::OUStringToOString( m_secureURL[j], + RTL_TEXTENCODING_ASCII_US ).pData->buffer); +#ifdef WIN32 + OSL_TRACE("case insensitive comparison"); + if( path.equalsIgnoreAsciiCase( m_secureURL[j] ) ) +#else + OSL_TRACE("case sensitive comparison"); + if( path.equals( m_secureURL[j] ) ) +#endif + { + match = true; + break; + } + } + return match; +} + +short ScriptSecurityManager::executeStandardDialog() +throw ( RuntimeException ) +{ + OUString dummyString; + return executeDialog( dummyString ); +} + +short ScriptSecurityManager::executePathDialog( const OUString & path ) +throw ( RuntimeException ) +{ + return executeDialog( path ); +} + +short ScriptSecurityManager::executeDialog( const OUString & path ) +throw ( RuntimeException ) +{ + Sequence < Any > aArgs; + if( path.getLength() != 0 ) + { + OSL_TRACE("reallocing"); + aArgs.realloc(1); + aArgs[ 0 ] <<= path; + } + short result; + try + { + Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager(); + validateXRef( xMgr, + "ScriptSecurityManager::executeDialog: cannot get ServiceManager" ); + Reference< XInterface > xInterface = + xMgr->createInstanceWithArgumentsAndContext( s_securityDialog, + aArgs, m_xContext ); + validateXRef( xInterface, "ScriptSecurityManager::executeDialog: Can't create SecurityDialog" ); + Reference< awt::XDialog > xDialog( xInterface, UNO_QUERY_THROW ); + result = xDialog->execute(); + Reference< lang::XComponent > xComponent( xInterface, UNO_QUERY_THROW ); + validateXRef( xInterface, "ScriptSecurityManager::executeDialog: Can't get XComponent to dispose dialog" ); + xComponent->dispose(); + } + catch ( RuntimeException & rte ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager::executeDialog: caught RuntimeException: ").concat( rte.Message ), + Reference< XInterface > ()); + } + catch ( Exception & e ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager::executeDialog: caught Exception: ").concat( e.Message ), + Reference< XInterface > ()); + } + return result; +} + +/** + * checks to see whether the requested ScriptPermission is allowed. + * This was modelled after the Java AccessController, but at this time + * we can't see a good reason not to return a bool, rather than throw + * an exception if the request is not granted (as is the case in Java). + */ +void ScriptSecurityManager::checkPermission( const OUString & scriptStorageURL, + const OUString & permissionRequest ) + throw ( RuntimeException, lang::IllegalArgumentException, security::AccessControlException ) +{ + if( permissionRequest.equals( OUString::createFromAscii( "execute" ) ) ) + { + OSL_TRACE( + "ScriptSecurityManager::checkPermission: execute permission request for %s", + ::rtl::OUStringToOString( scriptStorageURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer); + Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL ); + Permission_Hash::const_iterator ph_itend = + m_permissionSettings.end(); + if ( ph_it != ph_itend ) + { + if ( ph_it->second.execPermission ) + { + return; + } + else + { + OSL_TRACE( "permission refused" ); + Any aPermission; + security::RuntimePermission permission; + permission.Name = OUString::createFromAscii( "execute" ).concat( scriptStorageURL ); + aPermission <<= permission; + throw security::AccessControlException( + OUString::createFromAscii( "ScriptSecurityManager::checkPermission: no execute permission for URL" ).concat( scriptStorageURL ), + Reference< XInterface > (), aPermission ); + } + } + // we should never get here!! + throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 0 ); + } + // inappropriate permission request + throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 1 ); +} + +void ScriptSecurityManager::removePermissionSettings ( ::rtl::OUString & scriptStorageURL ) +{ + Permission_Hash::const_iterator ph_it = + m_permissionSettings.find( scriptStorageURL ); + + if ( ph_it == m_permissionSettings.end() ) + { + OSL_TRACE( "Entry for storage url %s doesn't exist in map", + ::rtl::OUStringToOString( scriptStorageURL, + RTL_TEXTENCODING_ASCII_US ).pData->buffer); + return; + } + + // erase the entry from the hash + m_permissionSettings.erase( scriptStorageURL ); + +} + +void ScriptSecurityManager::readConfiguration() + throw ( RuntimeException) +{ + Reference< XInterface > xInterface; + try + { + beans::PropertyValue configPath; + configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" ); + configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" ); + Sequence < Any > aargs( 1 ); + aargs[ 0 ] <<= configPath; + validateXRef( m_xConfigProvFactory, + "ScriptSecurityManager::readConfiguration: ConfigProviderFactory no longer valid!" ); + xInterface = m_xConfigProvFactory->createInstanceWithArguments( s_configAccess, + aargs ); + validateXRef( xInterface, + "ScriptSecurityManager::readConfiguration: cannot get ConfigurationAccess" ); + // get the XPropertySet interface from the ConfigurationAccess service + Reference < beans::XPropertySet > xPropSet( xInterface, UNO_QUERY ); + Any value; + + value=xPropSet->getPropertyValue( OUSTR( "Confirmation" ) ); + if ( sal_False == ( value >>= m_confirmationRequired ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: can't get Confirmation setting" ), + Reference< XInterface > () ); + } + if ( m_confirmationRequired == sal_True ) + { + OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is true" ); + } + else + { + OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is false" ); + } + value=xPropSet->getPropertyValue( OUSTR( "Warning" ) ); + if ( sal_False == ( value >>= m_warning ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: can't get Warning setting" ), + Reference< XInterface > () ); + } + if ( m_warning == sal_True ) + { + OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is true" ); + } + else + { + OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is false" ); + } + value=xPropSet->getPropertyValue( OUSTR( "OfficeBasic" ) ); + if ( sal_False == ( value >>= m_runMacroSetting ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: can't get OfficeBasic setting" ), + Reference< XInterface > () ); + } + OSL_TRACE( "ScriptSecurityManager:readConfiguration: OfficeBasic = %d", m_runMacroSetting ); + value=xPropSet->getPropertyValue( OUSTR( "SecureURL" ) ); + if ( sal_False == ( value >>= m_secureURL ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: can't get SecureURL setting" ), + Reference< XInterface > () ); + } + } + catch ( beans::UnknownPropertyException & upe ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: Attempt to read unknown property: " ).concat( upe.Message ), + Reference< XInterface > () ); + } + catch ( lang::WrappedTargetException & wte ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: wrapped target exception? :" ).concat( wte.Message ), + Reference< XInterface > () ); + } + catch ( Exception & e ) + { + OSL_TRACE( "Unknown exception in readconf: %s", + ::rtl::OUStringToOString(e.Message , + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ).concat( e.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + OSL_TRACE( "Completely Unknown exception in readconf!!!!!!"); + throw RuntimeException( + OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ), + Reference< XInterface > () ); + } +#endif + + int length = m_secureURL.getLength(); + + // PathSubstitution needed to interpret variables found in config + Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager(); + validateXRef( xMgr, + "ScriptSecurityManager::readConfiguration: cannot get XMultiComponentFactory" ); + xInterface = xMgr->createInstanceWithContext( + ::rtl::OUString::createFromAscii( + "com.sun.star.util.PathSubstitution"), m_xContext); + validateXRef( xInterface, + "ScriptSecurityManager::readConfiguration: cannot get ConfigurationProvider" ); + Reference< util::XStringSubstitution > xStringSubstitution( + xInterface, UNO_QUERY); + validateXRef( xStringSubstitution, + "ScriptSecurityManager::readConfiguration: cannot get ConfigurationProvider" ); + for( int i = 0; i < length; i++ ) + { + OSL_TRACE( "ScriptSecurityManager:readConfiguration path = %s", + ::rtl::OUStringToOString(m_secureURL[i] , + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + OSL_TRACE( "ScriptSecurityManager: subpath = %s", + ::rtl::OUStringToOString( + xStringSubstitution->substituteVariables( m_secureURL[i], true ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + m_secureURL[i] = xStringSubstitution->substituteVariables( m_secureURL[i], true ); + } +#ifdef _DEBUG + int length2 = m_secureURL.getLength(); + for( int j = 0; j < length2 ; j++ ) + { + OSL_TRACE( "ScriptSecurityManager: path = %s", + ::rtl::OUStringToOString(m_secureURL[j] , + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } +#endif +} + +void ScriptSecurityManager::addToSecurePaths( const OUString & path ) +throw ( RuntimeException ) +{ + OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths" ); + beans::PropertyValue configPath; + configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" ); + configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" ); + Sequence < Any > aargs( 1 ); + aargs[ 0 ] <<= configPath; + Reference< XInterface > xInterface = m_xConfigProvFactory->createInstanceWithArguments( s_configUpdate, + aargs ); + validateXRef( xInterface, + "ScriptSecurityManager::addToSecurePaths: ScriptSecurityManager: cannot get ConfigurationUpdateAccess" ); + Reference < container::XNameReplace > xNameReplace( xInterface, UNO_QUERY ); + validateXRef( xNameReplace, + "ScriptSecurityManager::addToSecurePaths: ScriptSecurityManager: cannot get XNameReplace" ); + Reference < util::XChangesBatch > xChangesBatch( xInterface, UNO_QUERY ); + validateXRef( xChangesBatch, + "ScriptSecurityManager::addToSecurePaths: cannot get XChangesBatch" ); + + OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths: after if stuff" ); + Reference < beans::XPropertySet > xPropSet( xInterface, UNO_QUERY ); + css::uno::Sequence< rtl::OUString > newSecureURL; + Any value; + OUString pathListPropName = OUSTR ( "SecureURL" ); + value=xPropSet->getPropertyValue( pathListPropName ); + if ( sal_False == ( value >>= newSecureURL ) ) + { + throw RuntimeException( + OUSTR( "ScriptSecurityManager::addToSecurePaths: can't get SecureURL setting" ), + Reference< XInterface > () ); + } + try + { + sal_Int32 length = newSecureURL.getLength(); + newSecureURL.realloc( length + 1 ); + newSecureURL[ length ] = path; + Any aNewSecureURL; + aNewSecureURL <<= newSecureURL; + xNameReplace->replaceByName( pathListPropName, aNewSecureURL ); + xChangesBatch->commitChanges(); + m_secureURL = newSecureURL; + } + catch ( Exception & e ) + { + OSL_TRACE( "Error updating secure paths: " ); + throw RuntimeException( + OUSTR( "ScriptSecurityManager::addToSecurePaths: error updating SecureURL setting" ).concat( e.Message ), + Reference< XInterface > () ); + } +} + +//************************************************************************* +// ScriptSecurityManager Destructor +ScriptSecurityManager::~ScriptSecurityManager() +{ + OSL_TRACE( "< ScriptSecurityManager dtor called >\n" ); +} + +} // Namespace diff --git a/scripting/source/storage/ScriptSecurityManager.hxx b/scripting/source/storage/ScriptSecurityManager.hxx new file mode 100755 index 000000000000..29ca511f88f3 --- /dev/null +++ b/scripting/source/storage/ScriptSecurityManager.hxx @@ -0,0 +1,99 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + + +#ifndef _FRAMEWORK_SCRIPT_SCRIPTSECURITYMANAGER_HXX_ +#define _FRAMEWORK_SCRIPT_SCRIPTSECURITYMANAGER_HXX_ + +#include <hash_map> +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/security/AccessControlException.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfo.hpp> + +namespace scripting_securitymgr +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +struct StoragePerm { + rtl::OUString scriptStorageURL; + sal_Int32 storageID; + sal_Bool execPermission; +}; + +typedef ::std::hash_map< ::rtl::OUString, StoragePerm, ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > Permission_Hash; +/** + * Class responsible for managing the ScriptSecurity. + */ +class ScriptSecurityManager +{ +public: + explicit ScriptSecurityManager( + const css::uno::Reference< css::uno::XComponentContext > & xContext ) + throw ( css::uno::RuntimeException ); + ~ScriptSecurityManager(); + void addScriptStorage( rtl::OUString scriptStorageURL, sal_Int32 storageID) + throw ( css::uno::RuntimeException ); +/** + * checks to see if the requested permission can be granted + * checks to see whether the requested ScriptPeremission is allowed. + */ + void checkPermission( const rtl::OUString & scriptStorageURL, + const rtl::OUString & permissionRequest ) + throw ( css::uno::RuntimeException, css::lang::IllegalArgumentException, + css::security::AccessControlException ); + void removePermissionSettings ( ::rtl::OUString & scriptStorageURL ); +private: + void readConfiguration() throw (css::uno::RuntimeException); + + short executeDialog ( const rtl::OUString & path ) + throw (css::uno::RuntimeException); + short executeStandardDialog() + throw ( css::uno::RuntimeException ); + short executePathDialog(const rtl::OUString & path) + throw ( css::uno::RuntimeException ); + + void addToSecurePaths ( const rtl::OUString & path ) + throw (css::uno::RuntimeException); + bool isSecureURL( const rtl::OUString & path ); + css::uno::Reference< css::uno::XComponentContext > m_xContext; + sal_Bool m_confirmationRequired; + sal_Bool m_warning; + sal_Int32 m_runMacroSetting; + css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvFactory; + css::uno::Sequence< rtl::OUString > m_secureURL; + Permission_Hash m_permissionSettings; + +}; +} // scripting_securitymgr + +#endif //_FRAMEWORK_SCRIPT_SCRIPTSECURITYMANAGER_HXX_ diff --git a/scripting/source/storage/ScriptStorage.cxx b/scripting/source/storage/ScriptStorage.cxx new file mode 100644 index 000000000000..7315e9d35dd5 --- /dev/null +++ b/scripting/source/storage/ScriptStorage.cxx @@ -0,0 +1,895 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <osl/file.hxx> +#include <osl/time.h> +#include <cppuhelper/implementationentry.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <util/util.hxx> +#include <rtl/uri.hxx> + + +#include "ScriptData.hxx" +#include "ScriptInfo.hxx" +#include "ScriptStorage.hxx" +#include "ScriptElement.hxx" +#include "ScriptMetadataImporter.hxx" +#include "ScriptURI.hxx" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +namespace scripting_impl +{ + +ScriptLanguages_hash* ScriptStorage::mh_scriptLangs = NULL; + +const sal_Char* const SERVICE_NAME = + "drafts.com.sun.star.script.framework.storage.ScriptStorage"; +const sal_Char* const IMPL_NAME = + "drafts.com.sun.star.script.framework.storage.ScriptStorage"; + +const sal_Char * const SCRIPT_DIR = "/Scripts"; +const sal_Char * const SCRIPT_PARCEL = "/parcel-descriptor.xml"; +const sal_Char * const SCRIPT_PARCEL_NAME_ONLY = "parcel-descriptor"; + +static OUString ss_implName = OUString::createFromAscii( IMPL_NAME ); +static OUString ss_serviceName = OUString::createFromAscii( SERVICE_NAME ); +static Sequence< OUString > ss_serviceNames = + Sequence< OUString >( &ss_serviceName, 1 ); + +const sal_uInt16 NUMBER_STORAGE_INITIALIZE_ARGS = 3; + +//extern ::rtl_StandardModuleCount s_moduleCount; + + + +//************************************************************************* +ScriptStorage::ScriptStorage( const Reference < + XComponentContext > & xContext ) +throw ( RuntimeException ) + : m_xContext( xContext ), m_bInitialised( false ) +{ + OSL_TRACE( "< ScriptStorage ctor called >\n" ); + + validateXRef( m_xContext, + "ScriptStorage::ScriptStorage : cannot get component context" ); + + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, + "ScriptStorage::ScriptStorage : cannot get service manager" ); + + if( !mh_scriptLangs ) + { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( !mh_scriptLangs ) + { + mh_scriptLangs = new ScriptLanguages_hash(); + Reference< XInterface > xInterface = + m_xMgr->createInstanceWithContext( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ) + , m_xContext ); + validateXRef( xInterface, + "ScriptStorage::ScriptStorage: cannot get ConfigurationProvider" ); + // create an instance of the ConfigurationAccess for accessing the + // scripting runtime settings + Reference< lang::XMultiServiceFactory > xConfigProvFactory = + Reference < lang::XMultiServiceFactory > + ( xInterface, UNO_QUERY_THROW ); + validateXRef( xConfigProvFactory, + "ScriptStorage::ScriptStorage: cannot get XMultiServiceFactory interface from ConfigurationProvider" ); + beans::PropertyValue configPath; + configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" ); + configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Scripting/ScriptRuntimes" ); + Sequence < Any > aargs( 1 ); + aargs[ 0 ] <<= configPath; + + xInterface = xConfigProvFactory->createInstanceWithArguments( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess"), + aargs ); + validateXRef( xInterface, + "ScriptStorage::ScriptStorage: cannot get ConfigurationAccess" ); + Reference< container::XNameAccess > xNameAccess = + Reference < container::XNameAccess > ( xInterface, + UNO_QUERY_THROW ); + validateXRef( xNameAccess, + "ScriptStorage::ScriptStorage: cannot get ConfigurationAccess" ); + Sequence< OUString > names = xNameAccess->getElementNames(); + for( int i = 0 ; i < names.getLength() ; i++ ) + { + OSL_TRACE( "Getting propertyset for Lang=%s", + ::rtl::OUStringToOString( names[i], RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + Reference< beans::XPropertySet > xPropSet = + Reference< beans::XPropertySet >( xNameAccess->getByName(names[i]), + UNO_QUERY_THROW ); + validateXRef( xPropSet, + "ScriptStorage::ScriptStorage: cannot get XPropertySet for name" ); + Any aProp = xPropSet->getPropertyValue( + OUString::createFromAscii( "SupportedFileExtensions") ); + Sequence< OUString > extns; + if( sal_False == ( aProp >>= extns ) ) + { + throw RuntimeException( + OUSTR( "ScriptStorage:ScriptStorage: can't get runtime extensions" ), + Reference< XInterface > () ); + } + for( int j = 0 ; j < extns.getLength() ; j++ ) + { + OSL_TRACE( "Adding Lang=%s, Extn=%s\n", + ::rtl::OUStringToOString( names[i], RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( extns[j], RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + (*mh_scriptLangs)[ extns[j] ] = + names[i]; + } + } + } + } +// s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt ); +} + +//************************************************************************* +ScriptStorage::~ScriptStorage() SAL_THROW( () ) +{ + OSL_TRACE( "< ScriptStorage dtor called >\n" ); +// s_moduleCount.modCnt.release( &s_moduleCount.modCnt ); +} + +//************************************************************************* +void +ScriptStorage::initialize( const Sequence <Any> & args ) +throw ( RuntimeException, Exception ) +{ + OSL_TRACE( "Entering ScriptStorage::initialize\n" ); + + // Should not be renitialised + if ( m_bInitialised ) + { + throw RuntimeException( + OUSTR( "ScriptStorage::initalize already initialized" ), + Reference<XInterface> () ); + } + + { // Protect member variable writes + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + + // Check args + if ( args.getLength() != NUMBER_STORAGE_INITIALIZE_ARGS ) + { + OSL_TRACE( "ScriptStorage::initialize: got wrong number of args\n" ); + throw RuntimeException( + OUSTR( "Invalid number of arguments provided!" ), + Reference< XInterface >() ); + } + + if ( sal_False == ( args[ 0 ] >>= m_xSimpleFileAccess ) ) + { + throw RuntimeException( + OUSTR( "Invalid XSimpleFileAccess argument provided!" ), + Reference< XInterface >() ); + } + + if ( sal_False == ( args[ 1 ] >>= m_scriptStorageID ) ) + { + throw RuntimeException( + OUSTR( "Invalid ScriptStorage ID argument provided!" ), + Reference< XInterface >() ); + + } + if ( sal_False == ( args[ 2 ] >>= m_stringUri ) ) + { + throw RuntimeException( + OUSTR( "Invalid String Uri argument provided!" ), + Reference< XInterface >() ); + } + } // End - Protect member variable writes + + OSL_TRACE( "uri: %s\n", ::rtl::OUStringToOString( + m_stringUri, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + try + { + // need to check for what??? + // what we have is a URI for the filesystem or document + // we need to check of the last element in the path has an + // extension that is associated with a script (eg. .bsh, .js etc) + OUString fileExtension = getFileExtension( m_stringUri ); + // and see if this is in our scripts map + ScriptLanguages_hash::iterator h_it = mh_scriptLangs->find( fileExtension ); + if ( h_it != mh_scriptLangs->end() ) + { + createForFilesystem( fileExtension ); + } + else + { + create(); + } + } + catch ( RuntimeException & re ) + { + OSL_TRACE( "caught com::sun::star::uno::RuntimeException in ScriptStorage::initialize" ); + throw RuntimeException( + OUSTR( "ScriptStorage::initalize RuntimeException: " ).concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & ue ) + { + OSL_TRACE( "caught com::sun::star::uno::Exception in ScriptStorage::initialize" ); + throw RuntimeException( + OUSTR( "ScriptStorage::initalize Exception: " ).concat( ue.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + OSL_TRACE( "caught unknown Exception in ScriptStorage::initialize" ); + throw RuntimeException( + OUSTR( "ScriptStorage::initalize unknown exception: " ), + Reference< XInterface > () ); + } +#endif + + OSL_TRACE( "Parsed the XML\n" ); + + m_bInitialised = true; +} + +void +ScriptStorage::create() +throw ( RuntimeException, Exception ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + try + { + // clear existing hashmap - rebuilding from scratch to avoid having + // to search for deleted elements on refresh + mh_implementations.clear(); + + OUString xStringUri(m_stringUri); + + ScriptMetadataImporter* SMI = new ScriptMetadataImporter( m_xContext ); + Reference< xml::sax::XExtendedDocumentHandler > xSMI( SMI ); + + validateXRef( xSMI, "ScriptStorage::create: failed to obtain valid XExtendedDocumentHandler" ); + + xStringUri = xStringUri.concat( ::rtl::OUString::createFromAscii( + SCRIPT_DIR ) ); + + // No Scripts directory - just return + if ( ! m_xSimpleFileAccess->isFolder( xStringUri ) ) + { + OSL_TRACE( "ScriptStorage::initialize: no Scripts dir for this storage - install problem\n" ); + return; + } + + // get the list of language folders under the Scripts directory + Sequence< ::rtl::OUString > languageDirs = + m_xSimpleFileAccess->getFolderContents( xStringUri, true ); + + Reference< io::XInputStream > xInput; + sal_Int32 languageDirsLength = languageDirs.getLength(); + for ( sal_Int32 i = 0; i < languageDirsLength ; ++i ) + { + OSL_TRACE( "contains: %s\n", ::rtl::OUStringToOString( + languageDirs[ i ], RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + if ( ! m_xSimpleFileAccess->isFolder( languageDirs[ i ] ) ) + { + continue; + } + + //get the list of parcel folders for each language folder + // under Scripts + Sequence< ::rtl::OUString > parcelDirs = + m_xSimpleFileAccess->getFolderContents( languageDirs[ i ], true ); + + sal_Int32 parcelDirsLength = parcelDirs.getLength(); + for ( sal_Int32 j = 0; j < parcelDirsLength ; ++j ) + { + OSL_TRACE( "contains: %s\n", + ::rtl::OUStringToOString( parcelDirs[ j ], + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + OUString parcelFile = parcelDirs[ j ].concat( + ::rtl::OUString::createFromAscii( SCRIPT_PARCEL ) ); + + // Do not have a valid parcel.xml + if ( !m_xSimpleFileAccess->exists( parcelFile ) || + m_xSimpleFileAccess->isFolder( parcelFile ) ) + { + continue; + } + OSL_TRACE( "parcel file: %s\n", + ::rtl::OUStringToOString( parcelFile, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + xInput = m_xSimpleFileAccess->openFileRead( parcelFile ); + // Failed to get input stream + if ( !xInput.is() ) + { + continue; + } + + OSL_TRACE( "Parse the metadata \n" ); + Datas_vec vScriptDatas; + try + { + SMI->parseMetaData( xInput, parcelDirs[ j ], vScriptDatas ); + } + catch ( xml::sax::SAXException & saxe ) + { + if ( xInput.is() ) + { + xInput->closeInput(); + } + OSL_TRACE( + "caught com::sun::star::xml::sax::SAXException in ScriptStorage::create %s", + ::rtl::OUStringToOString( saxe.Message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + continue; + } + catch ( io::IOException & ioe ) + { + if ( xInput.is() ) + { + xInput->closeInput(); + } + OSL_TRACE( + "caught com::sun::star::io::IOException in ScriptStorage::create" ); + continue; + } + xInput->closeInput(); + + updateMaps( vScriptDatas ); + } + } + } + catch ( io::IOException & ioe ) + { + //From ScriptMetadata Importer + OSL_TRACE( "caught com::sun::star::io::IOException in ScriptStorage::create" ); + throw RuntimeException( + OUSTR( "ScriptStorage::create IOException: " ).concat( ioe.Message ), + Reference< XInterface > () ); + + } + catch ( ucb::CommandAbortedException & cae ) + { + OSL_TRACE( "caught com::sun::star::ucb::CommandAbortedException in ScriptStorage::create" ); + throw RuntimeException( + OUSTR( + "ScriptStorage::create CommandAbortedException: " ).concat( cae.Message ), + Reference< XInterface > () ); + } + catch ( RuntimeException & re ) + { + OSL_TRACE( "caught com::sun::star::uno::RuntimeException in ScriptStorage::create" ); + throw RuntimeException( + OUSTR( "ScriptStorage::create RuntimeException: " ).concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & ue ) + { + OSL_TRACE( "caught com::sun::star::uno::Exception in ScriptStorage::create" ); + throw RuntimeException( + OUSTR( "ScriptStorage::create Exception: " ).concat( ue.Message ), + Reference< XInterface > () ); + } +#ifdef _DEBUG + catch ( ... ) + { + OSL_TRACE( "caught unknown Exception in ScriptStorage::create" ); + throw RuntimeException( + OUSTR( "ScriptStorage::initalize unknown exception: " ), + Reference< XInterface > () ); + } +#endif + + OSL_TRACE( "Parsed the XML\n" ); + + m_bInitialised = true; +} + +//************************************************************************* +// private method to create the usual data structures for scripts located +// on the filesystem. +// parcelURI = the path to the script +// functionName = the full filename with extension +// logicalName = the filename without the extension +void +ScriptStorage::createForFilesystem( const OUString & fileExtension ) +throw ( RuntimeException, Exception ) +{ + // need to decode as file urls are encoded + OUString xStringUri = ::rtl::Uri::decode( m_stringUri, + rtl_UriDecodeWithCharset, RTL_TEXTENCODING_ASCII_US ); + + // no x-platform issues here as we are dealing with URLs + sal_Int32 lastFileSep = xStringUri.lastIndexOf( '/' ); + // the char just after the filesep + lastFileSep += 1; + sal_Int32 lastFileExt = xStringUri.lastIndexOf( fileExtension ); + OUString searchString = OUString::createFromAscii( "://" ); + sal_Int32 searchStringLength = searchString.getLength(); + sal_Int32 startPath = xStringUri.indexOf( searchString ); + sal_Int32 uriLength = xStringUri.getLength(); + OUString fileNameNoExt = xStringUri.copy( lastFileSep , + lastFileExt - lastFileSep - 1 ); + OUString fileName = xStringUri.copy( lastFileSep, uriLength - lastFileSep ); + OUString filePath = xStringUri.copy( startPath + searchStringLength, + lastFileSep - startPath - searchStringLength ); + OUString filePathWithName = xStringUri.copy( startPath + searchStringLength, + uriLength - startPath - searchStringLength ); + + ScriptData scriptData; + scriptData.language = mh_scriptLangs->find( fileExtension )->second; + OSL_TRACE( "\t language = %s", ::rtl::OUStringToOString( + scriptData.language, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + // do we need to encode this? + scriptData.functionname = fileName; + OSL_TRACE( "\t functionName = %s", ::rtl::OUStringToOString( + scriptData.functionname, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + //scriptData.functionname = ::rtl::Uri::encode( fileName, + //rtl_UriCharClassUricNoSlash, rtl_UriEncodeCheckEscapes, + //RTL_TEXTENCODING_ASCII_US ); + + scriptData.parcelURI = filePath; + OSL_TRACE( "\t parcelURI = %s", ::rtl::OUStringToOString( + scriptData.parcelURI, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + scriptData.logicalname = fileNameNoExt; + OSL_TRACE( "\t logicalName = %s", ::rtl::OUStringToOString( + scriptData.logicalname, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + // and now push onto the usual structures + ScriptFunction_hash sfh; + sfh[ scriptData.functionname ] = scriptData; + mh_implementations[ scriptData.language ] = sfh; + m_bInitialised = true; +} + +//************************************************************************* +// private method to return the file extension, eg. bsh, js etc +OUString +ScriptStorage::getFileExtension( const OUString & stringUri ) +{ + OUString fileExtension; + sal_Int32 lastDot = stringUri.lastIndexOf( '.' ); + if( lastDot > 0 ) { + sal_Int32 stringUriLength = stringUri.getLength(); + fileExtension = stringUri.copy( lastDot +1 , stringUriLength - lastDot - 1 ); + } + else + { + fileExtension = OUString::createFromAscii(""); + } + return fileExtension; +} + +//************************************************************************* +// private method for updating hashmaps +void +ScriptStorage::updateMaps( const Datas_vec & vScriptDatas ) +{ + + Datas_vec::const_iterator it_end = vScriptDatas.end(); + // step through the vector of ScripImplInfos returned from parse + for ( Datas_vec::const_iterator it = vScriptDatas.begin() ; it != it_end; ++it ) + { + //find the Datas_vec for this logical name + ScriptData_hash::iterator h_it = mh_implementations.find( it->language ); + + if ( h_it == mh_implementations.end() ) + { + //if it's null, need to create a new Datas_vec + OSL_TRACE( + "updateMaps: new language: %s\n", rtl::OUStringToOString( + it->language, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + OSL_TRACE( + "updateMaps: adding functionname: %s\n", rtl::OUStringToOString( + it->functionname, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + ScriptFunction_hash sfh; + sfh[ it->functionname ] = *it; + mh_implementations[ it->language ] = sfh; + } + else + { + OSL_TRACE( + "updateMaps: adding functionname: %s\n", rtl::OUStringToOString( + it->functionname, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + OSL_TRACE( " language name: %s\n", + rtl::OUStringToOString( it->functionname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + h_it->second[ it->functionname ] = *it; + } + } +} + +//************************************************************************* +// XScriptStorageExport::save +void +ScriptStorage::save() +throw ( RuntimeException ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + Reference< io::XActiveDataSource > xSource; + Reference< io::XOutputStream > xOS; + + // xScriptInvocation = Reference<XScriptInvocation>(xx, UNO_QUERY_THROW); + Reference< xml::sax::XExtendedDocumentHandler > xHandler; + + OUString parcel_suffix = OUString::createFromAscii( SCRIPT_PARCEL ); + OUString ou_parcel = OUString( + RTL_CONSTASCII_USTRINGPARAM( SCRIPT_PARCEL_NAME_ONLY ) ); + + try + { + ScriptData_hash::iterator it_end = mh_implementations.end(); + for ( ScriptData_hash::iterator it = mh_implementations.begin() ; it != it_end; ++it ) + { + ::rtl::OUString logName = it->first; + ScriptFunction_hash::iterator it_sfh_end = it->second.end(); + for ( ScriptFunction_hash::iterator it_sfh = it->second.begin(); + it_sfh != it_sfh_end ; ++it_sfh ) + { + ScriptOutput_hash::const_iterator it_parcels = + mh_parcels.find( it_sfh->second.parcelURI ); + if ( it_parcels == mh_parcels.end() ) + { + //create new outputstream + OUString parcel_xml_path = it_sfh->second.parcelURI.concat( + parcel_suffix ); + m_xSimpleFileAccess->kill( parcel_xml_path ); + xOS = m_xSimpleFileAccess->openFileWrite( parcel_xml_path ); + + OSL_TRACE( "saving: %s\n", rtl::OUStringToOString( + it_sfh->second.parcelURI.concat( OUString::createFromAscii( + "/parcel.xml" ) ), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + Reference< XInterface > xInterface = + m_xMgr->createInstanceWithContext( + OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ), + m_xContext ); + validateXRef( xInterface, "ScriptStorage::save: cannot get sax.Writer" ); + xHandler = Reference<xml::sax::XExtendedDocumentHandler>( + xInterface, UNO_QUERY_THROW ); + xSource = Reference< io::XActiveDataSource >( + xHandler, UNO_QUERY_THROW ); + xSource->setOutputStream( xOS ); + + writeMetadataHeader( xHandler ); + + mh_parcels[ it_sfh->second.parcelURI ] = xHandler; + } + else + { + xHandler = it_parcels->second; + } + + ScriptElement* pSE = new ScriptElement( it_sfh->second ); + // this is to get pSE released correctly + Reference < xml::sax::XAttributeList > xal( pSE ); + pSE->dump( xHandler ); + } + } + + ScriptOutput_hash::const_iterator out_it_end = mh_parcels.end(); + + for ( ScriptOutput_hash::const_iterator out_it = mh_parcels.begin(); + out_it != out_it_end; ++out_it ) + { + out_it->second->ignorableWhitespace( ::rtl::OUString() ); + out_it->second->endDocument(); + xSource.set( out_it->second, UNO_QUERY ); + Reference< io::XOutputStream > xOS = xSource->getOutputStream(); + xOS->closeOutput(); + + } + + // clear the hash map, as all output streams have been closed. + // need to re-create on next save + mh_parcels.clear(); + } + // *** TODO - other exception handling IO etc. + catch ( RuntimeException & re ) + { + OSL_TRACE( "caught com::sun::star::uno::RuntimeException in ScriptStorage::save" ); + throw RuntimeException( + OUSTR( "ScriptStorage::save RuntimeException: " ).concat( + re.Message ), + Reference< XInterface > () ); + } +} + +//************************************************************************* +void +ScriptStorage::refresh() +throw (RuntimeException) +{ + OSL_TRACE("** => ScriptStorage: in refresh()\n"); + + // guard against concurrent refreshes + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + + try + { + create(); + + } + catch ( RuntimeException & re ) + { + OSL_TRACE( "caught com::sun::star::uno::RuntimeException in ScriptStorage::refresh" ); + throw RuntimeException( + OUSTR( "ScriptStorage::refresh RuntimeException: " ).concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & ue ) + { + OSL_TRACE( "caught com::sun::star::uno::Exception in ScriptStorage::refresh" ); + throw RuntimeException( + OUSTR( "ScriptStorage::refresh Exception: " ).concat( ue.Message ), + Reference< XInterface > () ); + } +} + +//************************************************************************* +void +ScriptStorage::writeMetadataHeader( + Reference <xml::sax::XExtendedDocumentHandler> & xHandler ) +{ + xHandler->startDocument(); + OUString aDocTypeStr( RTL_CONSTASCII_USTRINGPARAM( + "<!DOCTYPE parcel SYSTEM \"scripting.dtd\">" ) ); + xHandler->unknown( aDocTypeStr ); + xHandler->ignorableWhitespace( OUString() ); +} + + +//************************************************************************* +Sequence< ::rtl::OUString > +ScriptStorage::getScriptLogicalNames() +throw ( RuntimeException ) +{ + Sequence< ::rtl::OUString > results; + // comment out the rest, and ultimately remove method + /*ScriptInfo_hash::iterator h_it = mh_implementations.begin(); + ScriptInfo_hash::iterator h_itEnd = mh_implementations.end(); + if ( h_it == h_itEnd ) + { + OSL_TRACE( "ScriptStorage::getImplementations: EMPTY STORAGE"); + return results; + } + results.realloc( mh_implementations.size() ); + + //find the implementations for the given logical name + try + { + + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + + for ( sal_Int32 count = 0; h_it != h_itEnd ; ++h_it ) + { + ::rtl::OUString logicalName = h_it->first; + OSL_TRACE( "Adding %s at index %d ", ::rtl::OUStringToOString( + logicalName, RTL_TEXTENCODING_ASCII_US ).pData->buffer, count); + results[ count++ ] = logicalName; + } + + } + catch ( RuntimeException & re ) + { + throw RuntimeException( + OUSTR( "ScriptStorage::getScriptLogicalNames RuntimeException: " ).concat( re.Message ), + Reference< XInterface > () ); + } + catch ( Exception & e ) + { + throw RuntimeException( OUSTR( + "ScriptStorage::getScriptLogicalNames Exception: " ).concat( + e.Message ), Reference< XInterface > () ); + } */ + return results; +} + +//************************************************************************* +Sequence< Reference< storage::XScriptInfo > > +ScriptStorage::getImplementations( const ::rtl::OUString & queryURI ) +throw ( lang::IllegalArgumentException, + RuntimeException ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); +// format is script:://[function_name]?language=[languge]&location=[location] +// LogicalName is now not used anymore, further more the ScriptURI class +// will be retired also and a new UNO service will be used. Additionally the +// parcel-description will also need to be modified to remove logical name +// ScriprtMetaDataImporter has been modified to ignore the Logical name +// definined in the parcel-desc.xml. As an interim temp solution the Datas_vec +// structure that is returned from ScriptMetDataImporter sets the logicalname +// to the function name. ScriptURI class has been changed in the same way. +// + Sequence< Reference< storage::XScriptInfo > > results; + ScriptURI scriptURI( queryURI ); + OSL_TRACE( "getting impl for language %s, function name: %s", + ::rtl::OUStringToOString( scriptURI.getLanguage(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer, + ::rtl::OUStringToOString( scriptURI.getFunctionName(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + ScriptData_hash::iterator h_itEnd = mh_implementations.end(); + ScriptData_hash::iterator h_it = mh_implementations.begin(); + if ( h_it == h_itEnd ) + { + OSL_TRACE( "ScriptStorage::getImplementations: EMPTY STORAGE" ); + return results; + } + + //find the implementations for the given language + h_it = mh_implementations.find( scriptURI.getLanguage() ); + + if ( h_it == h_itEnd ) + { + OSL_TRACE( "ScriptStorage::getImplementations: no impls found for %s", + ::rtl::OUStringToOString( scriptURI.getLanguage(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return results; + } + + //find the implementations for the given language + ScriptFunction_hash::const_iterator it_datas = h_it->second.find( + scriptURI.getLogicalName() ); + ScriptFunction_hash::const_iterator it_datas_end = h_it->second.end(); + + if ( it_datas == it_datas_end ) + { + OSL_TRACE( "ScriptStorage::getImplementations: no impls found for %s", + ::rtl::OUStringToOString( scriptURI.getFunctionName(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return results; + } + + results.realloc( 1 ); + ScriptData scriptData = it_datas->second; + OSL_TRACE( "ScriptStorage::getImplementations: impls found for %s", + ::rtl::OUStringToOString( scriptData.functionname, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + Reference< storage::XScriptInfo > xScriptInfo = + new ScriptInfo ( scriptData, m_scriptStorageID ); + results[ 0 ] = xScriptInfo; + + return results; +} + +//************************************************************************* +Sequence< Reference< storage::XScriptInfo > > SAL_CALL +ScriptStorage::getAllImplementations() throw ( RuntimeException ) +{ + ::osl::Guard< osl::Mutex > aGuard( m_mutex ); + Sequence< Reference< storage::XScriptInfo > > results; + ScriptData_hash::iterator h_itEnd = mh_implementations.end(); + ScriptData_hash::iterator h_it = mh_implementations.begin(); + if ( h_it == h_itEnd ) + { + OSL_TRACE( "ScriptStorage::getImplementations: EMPTY STORAGE" ); + return results; + } + + + //iterate through each logical name and gather each implementation + //for that name + for ( sal_Int32 count = 0; h_it != h_itEnd; ++h_it ) + { + results.realloc( h_it->second.size() + count ); + OSL_TRACE( "Adding implementations for %s", + ::rtl::OUStringToOString( h_it->first, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + ScriptFunction_hash::const_iterator it_sfh = h_it->second.begin(); + ScriptFunction_hash::const_iterator it_sfh_end = h_it->second.end(); + OSL_TRACE( "Adding %d to sequence of impls ", h_it->second.size() ); + for ( ; it_sfh != it_sfh_end ; ++it_sfh ) + { + Reference< storage::XScriptInfo > xScriptInfo = new ScriptInfo ( + it_sfh->second, m_scriptStorageID ); + + results[ count++ ] = xScriptInfo; + } + } + return results; + +} + +//************************************************************************* +OUString SAL_CALL ScriptStorage::getImplementationName( ) +throw( RuntimeException ) +{ + return ss_implName; +} + +//************************************************************************* +sal_Bool SAL_CALL ScriptStorage::supportsService( const OUString& serviceName ) +throw( RuntimeException ) +{ + OUString const * pNames = ss_serviceNames.getConstArray(); + for ( sal_Int32 nPos = ss_serviceNames.getLength(); nPos--; ) + { + if ( serviceName.equals( pNames[ nPos ] ) ) + { + return sal_True; + } + } + return sal_False; +} + +//************************************************************************* +Sequence<OUString> SAL_CALL ScriptStorage::getSupportedServiceNames( ) +throw( RuntimeException ) +{ + return ss_serviceNames; +} + +} // namespace scripting_impl + + +namespace scripting_runtimemgr +{ + +//************************************************************************* +Reference<XInterface> SAL_CALL ss_create( + const Reference< XComponentContext > & xCompC ) +{ + return ( cppu::OWeakObject * ) new ::scripting_impl::ScriptStorage( xCompC ); +} + +//************************************************************************* +Sequence<OUString> ss_getSupportedServiceNames( ) +SAL_THROW( () ) +{ + return ::scripting_impl::ss_serviceNames; +} + +//************************************************************************* +OUString ss_getImplementationName( ) +SAL_THROW( () ) +{ + return ::scripting_impl::ss_implName; +} +}//end namespace diff --git a/scripting/source/storage/ScriptStorage.hxx b/scripting/source/storage/ScriptStorage.hxx new file mode 100644 index 000000000000..a94e2abc3027 --- /dev/null +++ b/scripting/source/storage/ScriptStorage.hxx @@ -0,0 +1,205 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef __SCRIPTING_STORAGE_SCRIPTSTORAGE_HXX_ +#define __SCRIPTING_STORAGE_SCRIPTSTORAGE_HXX_ + +#include <vector> +#include <hash_map> + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase5.hxx> // helper for component factory + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageExport.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageRefresh.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfo.hpp> + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +//Typedefs +//============================================================================= +typedef ::std::vector< ScriptData > Datas_vec; +//----------------------------------------------------------------------------- +// function name -> ScriptData +typedef ::std::hash_map < ::rtl::OUString, ScriptData, ::rtl::OUStringHash, + ::std::equal_to< ::rtl::OUString > > ScriptFunction_hash; +//----------------------------------------------------------------------------- +// language -> hash of function name -> ScriptData +typedef ::std::hash_map < ::rtl::OUString, ScriptFunction_hash, + ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > +ScriptData_hash; +//----------------------------------------------------------------------------- +typedef ::std::hash_map < ::rtl::OUString, +css::uno::Reference< css::xml::sax::XExtendedDocumentHandler >, +::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > +ScriptOutput_hash; +//----------------------------------------------------------------------------- +typedef ::std::hash_map < ::rtl::OUString, +::rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > +ScriptLanguages_hash; + +//============================================================================= + +class ScriptStorage : public + ::cppu::WeakImplHelper5< + css::lang::XServiceInfo, + css::lang::XInitialization, + dcsssf::storage::XScriptInfoAccess, + dcsssf::storage::XScriptStorageExport, + dcsssf::storage::XScriptStorageRefresh > +{ +public: + //Constructors and Destructors + //========================================================================= + explicit ScriptStorage( + const css::uno::Reference< css::uno::XComponentContext > & xContext ) + throw ( css::uno::RuntimeException ); + //------------------------------------------------------------------------- + virtual ~ScriptStorage() SAL_THROW( () ); + //========================================================================= + + // XServiceInfo impl + //========================================================================= + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw ( css::uno::RuntimeException ); + //------------------------------------------------------------------------- + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString & ServiceName ) + throw ( css::uno::RuntimeException ); + //------------------------------------------------------------------------- + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw ( css::uno::RuntimeException ); + //------------------------------------------------------------------------- + static css::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames_Static(); + //========================================================================= + + // XInitialization impl + //========================================================================= + virtual void SAL_CALL + initialize( css::uno::Sequence< css::uno::Any > const & args ) + throw ( css::uno::RuntimeException, css::uno::Exception ); + //========================================================================= + + //XScriptInfoAccess + //========================================================================= + /** + * Get the logical names for this storage + * + * @return sequence < ::rtl::OUString > + * The logical names + */ + virtual css::uno::Sequence< ::rtl::OUString > + SAL_CALL getScriptLogicalNames() + throw ( css::uno::RuntimeException ); + + //========================================================================= + /** + * Get the implementations for a given URI + * + * @param queryURI + * The URI to get the implementations for + * + * @return sequence < XScriptInfo > + * The URIs of the implementations + */ + virtual css::uno::Sequence< css::uno::Reference< dcsssf::storage::XScriptInfo > > + SAL_CALL getImplementations( + const ::rtl::OUString& queryURI ) + throw ( css::lang::IllegalArgumentException, css::uno::RuntimeException ); + + //========================================================================= + /** + * Get all script implementations + * + * + * @return sequence < XScriptInfo > + * script implementations + */ + virtual css::uno::Sequence< css::uno::Reference< dcsssf::storage::XScriptInfo > > + SAL_CALL getAllImplementations() + throw ( css::uno::RuntimeException ); + + //========================================================================= + + /** + * Save the scripts stored in the ScriptStorage into the corresponding + * area (document or application) + */ + void SAL_CALL save() + throw ( css::uno::RuntimeException ); + //========================================================================= + + /** + * Refresh the ScriptStorage from the data stored in the corresponding area + * (document or application). + */ + void SAL_CALL refresh() + throw ( css::uno::RuntimeException ); + //========================================================================= + +private: + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::ucb::XSimpleFileAccess > m_xSimpleFileAccess; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMgr; + + ::std::vector < ::rtl::OUString > mv_logicalNames; + static ScriptLanguages_hash* mh_scriptLangs; + ScriptData_hash mh_implementations; + ScriptOutput_hash mh_parcels; + sal_Int32 m_scriptStorageID; + ::rtl::OUString m_stringUri; + + osl::Mutex m_mutex; + bool m_bInitialised; + + void updateMaps( const Datas_vec & vScriptDatas ); + void writeMetadataHeader( + css::uno::Reference < css::xml::sax::XExtendedDocumentHandler > & xExDocHandler ); + void create () + throw (css::uno::RuntimeException, css::uno::Exception); + void createForFilesystem ( const ::rtl::OUString & scriptLanguage ) + throw (css::uno::RuntimeException, css::uno::Exception); + ::rtl::OUString getFileExtension ( const ::rtl::OUString & stringUri ); + +}; // class ScriptingStorage + +} // namespace scripting_impl + +#endif diff --git a/scripting/source/storage/ScriptStorageManager.cxx b/scripting/source/storage/ScriptStorageManager.cxx new file mode 100644 index 000000000000..77ca5a45dd15 --- /dev/null +++ b/scripting/source/storage/ScriptStorageManager.cxx @@ -0,0 +1,573 @@ +/************************************************************************* +* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" + +#include <stdio.h> + +#include <cppuhelper/implementationentry.hxx> +#include <sal/config.h> +#include <rtl/uri.hxx> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp> + +#include "ScriptStorageManager.hxx" +#include <util/util.hxx> +#include <util/scriptingconstants.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::drafts::com::sun::star::script::framework; + +namespace scripting_impl +{ + +static OUString s_implName = + ::rtl::OUString::createFromAscii( + "drafts.com.sun.star.script.framework.storage.ScriptStorageManager" ); +static OUString s_serviceName = + ::rtl::OUString::createFromAscii( + "drafts.com.sun.star.script.framework.storage.ScriptStorageManager" ); +static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 ); + +//extern ::rtl_StandardModuleCount s_moduleCount = MODULE_COUNT_INIT; +//extern ::rtl_StandardModuleCount s_moduleCount; + + +//************************************************************************* +// ScriptStorageManager Constructor +ScriptStorageManager::ScriptStorageManager( const Reference< + XComponentContext > & xContext ) SAL_THROW ( ( RuntimeException ) ) + : m_xContext( xContext ), m_count( 0 ), m_securityMgr( xContext ) +{ + OSL_TRACE( "< ScriptStorageManager ctor called >\n" ); + //s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt ); + + validateXRef( m_xContext, + "ScriptStorageManager::ScriptStorageManager : cannot get component context" ); + + m_xMgr = m_xContext->getServiceManager(); + validateXRef( m_xMgr, + "ScriptStorageManager::ScriptStorageManager : cannot get service manager" ); + + try + { + // obtain the macro expander singleton to use in determining the + // location of the application script storage + Any aAny = m_xContext->getValueByName( OUString::createFromAscii( + "/singletons/com.sun.star.util.theMacroExpander" ) ); + Reference< util::XMacroExpander > xME; + if ( sal_False == ( aAny >>= xME ) ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::ScriptStorageManager: can't get XMacroExpander" ), + Reference< XInterface >() ); + } + validateXRef( xME, "ScriptStorageManager constructor: can't get MacroExpander" ); + + OUString base = OUString::createFromAscii( + SAL_CONFIGFILE( "${$BRAND_BASE_DIR/program/bootstrap" ) ); + + setupAppStorage( xME, + base.concat( OUString::createFromAscii( "::BaseInstallation}/share" ) ), + OUSTR( "SHARE" ) ); + setupAppStorage( xME, + base.concat( OUString::createFromAscii( "::UserInstallation}/user" ) ), + OUSTR( "USER" ) ); + + } + catch ( Exception & e ) + { + throw RuntimeException( OUSTR( "ScriptStorageManager::ScriptStorageManager: " ).concat( e.Message ), Reference< XInterface >() ); + } + OSL_ASSERT( m_count == 2 ); +} + +//************************************************************************* +// ScriptStorageManager setupAppStorage +void +ScriptStorageManager::setupAppStorage( + const Reference< util::XMacroExpander > & xME, + const OUString & storageStr, + const OUString & appStr) +SAL_THROW ( ( RuntimeException ) ) +{ + try + { + Reference< XInterface > xInterface = + m_xMgr->createInstanceWithContext( + OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ); + validateXRef( xInterface, + "ScriptStorageManager constructor: can't get SimpleFileAccess XInterface" ); + Reference< ucb::XSimpleFileAccess > xSFA( xInterface, UNO_QUERY_THROW ); + + setupAnyStorage( xSFA, xME->expandMacros( storageStr ), appStr ); + } + catch ( Exception & e ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::setupAppStorage: " ).concat( e.Message ), + Reference< XInterface >() ); + } +} + +//************************************************************************* +// ScriptStorageManager setupAnyStorage +sal_Int32 +ScriptStorageManager::setupAnyStorage( + const Reference< ucb::XSimpleFileAccess > & xSFA, + const OUString & storageStr, + const OUString & origStringURI ) +SAL_THROW ( ( RuntimeException ) ) +{ + // Required for scope of fnc to protect all access read and writes to m_count + ::osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + try + { + + // create a ScriptingStorage using the SimpleFileAccess, the storageID + // (from the count), and the URL to the application's shared area + Sequence < Any > aArgs( 3 ); + aArgs[ 0 ] <<= xSFA; + aArgs[ 1 ] <<= m_count; + aArgs[ 2 ] <<= storageStr; + + OSL_TRACE( "creating storage for: %s\n", + ::rtl::OUStringToOString( storageStr, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + Reference< XInterface > xInterface = + m_xMgr->createInstanceWithArgumentsAndContext( + OUString::createFromAscii( + "drafts.com.sun.star.script.framework.storage.ScriptStorage" ), + aArgs, m_xContext ); + + validateXRef( xInterface, "ScriptStorageManager:: setupAnyStorage: Can't create ScriptStorage for share" ); + + // and place it in the hash_map. Increment the counter + m_ScriptStorageMap[ m_count++ ] = xInterface; + sal_Int32 sid = m_count - 1; + + // create hash of original uri i.e. file:///home/users/docs/mydoc.sxw + // and storage id (sid) this will allow us to retrieve + // the sid based on the url of the document. + m_StorageIdOrigURIHash [ origStringURI ] = sid; + OSL_TRACE( "\tcreated with ID=%d\n", m_count - 1 ); + + } + catch ( Exception & e ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::setupAnyStorage: " ).concat( + e.Message ), Reference< XInterface >() ); + } + + return m_count -1; +} + +//************************************************************************* +// ScriptStorageManager Destructor +ScriptStorageManager::~ScriptStorageManager() +SAL_THROW ( () ) +{ + OSL_TRACE( "< ScriptStorageManager dtor called >\n" ); +// s_moduleCount.modCnt.release( &s_moduleCount.modCnt ); +} + +//************************************************************************* +// This method assumes that the XSimpleFileAccess knows it's on root URL +// and can be used with relative URLs +sal_Int32 SAL_CALL +ScriptStorageManager::createScriptStorage( + const Reference< ucb::XSimpleFileAccess >& xSFA ) +throw ( RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptStorageManager in createScriptingStorage\n" ); + validateXRef( xSFA, + "ScriptStorageManager::createScriptStorage: XSimpleFileAccess is not valid" ); + + return setupAnyStorage( xSFA, ::rtl::OUString::createFromAscii( "" ), + ::rtl::OUString::createFromAscii( "" ) ); +} + +//************************************************************************* +sal_Int32 SAL_CALL +ScriptStorageManager::createScriptStorageWithURI( + const Reference< ucb::XSimpleFileAccess >& xSFA, const OUString & cStringURI ) +throw ( RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptStorageManager in createScriptingStorageWithURI\n" ); + validateXRef( xSFA, "ScriptStorageManager::createScriptStorage: XSimpleFileAccess is not valid" ); + + // related to issue 11866 + // warning dialog gets launched when adding binding to script in doc + // workaround issue: no functionProvider created on doc open + // if NODIALOG tag, strip from stringURI, set boolean=true + bool displayDialog = true; + ::rtl::OUString dialogTag = ::rtl::OUString::createFromAscii( "NoDialog::" ); + ::rtl::OUString stringURI = cStringURI; + if( stringURI.indexOf( dialogTag ) == 0 ) + { + OSL_TRACE( "ScriptStorageManager::createScriptStorage: will not display security dialogs" ); + stringURI = stringURI.copy( dialogTag.getLength() ); + displayDialog = false; + } + sal_Int32 returnedID = getScriptStorageID(stringURI); + + + // convert file:///... url to vnd... syntax + ::rtl::OUString canonicalURI( + ::rtl::OUString::createFromAscii( "vnd.sun.star.pkg://" ) ); + canonicalURI = canonicalURI.concat( ::rtl::Uri::encode( stringURI, + rtl_UriCharClassUricNoSlash, rtl_UriEncodeCheckEscapes, + RTL_TEXTENCODING_ASCII_US ) ); + + if (returnedID == -1) + { + OSL_TRACE("Creating new storage for %s", + ::rtl::OUStringToOString( stringURI, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + returnedID = setupAnyStorage( xSFA, canonicalURI, stringURI ); + } + else + { + OSL_TRACE("Using existing storage for %s", + ::rtl::OUStringToOString( stringURI, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + +// np - removed previous scripting framework security handling +// now handled by modification to existing calls in sfx for basic +// +/* if( displayDialog ) + { + try + { + OSL_TRACE("Adding to security mgr for %s", + ::rtl::OUStringToOString( stringURI, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + m_securityMgr.addScriptStorage( stringURI, returnedID ); + } + catch ( RuntimeException & rte ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::createScriptStorageWithURI: " ).concat( + rte.Message ), Reference< XInterface >() ); + } + } + else + { + OSL_TRACE("No need to security mgr for %s", + ::rtl::OUStringToOString( stringURI, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + }*/ + return returnedID; +} + +//************************************************************************* +Reference < XInterface > SAL_CALL +ScriptStorageManager::getScriptStorage( sal_Int32 scriptStorageID ) +throw( RuntimeException ) +{ + OSL_TRACE( "** ==> ScriptStorageManager in getStorageInstance\n" ); + OSL_TRACE( "** ==> request for id=%d",scriptStorageID ); + + ScriptStorage_map::const_iterator itr = + m_ScriptStorageMap.find( scriptStorageID ); + + if ( itr == m_ScriptStorageMap.end() ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::getScriptStorage: invalid storage ID" ), + Reference< XInterface >() ); + } + validateXRef( itr->second, + "ScriptStorageManager::getScriptStorage: Cannot get ScriptStorage from ScriptStorageHash" ); + return itr->second; +} + +//******************************************************************* +sal_Int32 SAL_CALL +ScriptStorageManager::getScriptStorageID( const ::rtl::OUString& origURI ) + throw (::com::sun::star::uno::RuntimeException) +{ + StorageId_hash::const_iterator it = m_StorageIdOrigURIHash.find( origURI ); + + if ( it == m_StorageIdOrigURIHash.end() ) + { + OUString message = OUSTR( "ScriptStorageManager::getScriptStorageID(): Cannot find storage for " ); + if ( origURI.getLength() == 0 ) + { + message = message.concat( OUSTR("Empty URI") ); + } + else + { + message = message.concat( origURI ); + } + OSL_TRACE( ::rtl::OUStringToOString( message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return -1; + } + + return it->second; +} + +//******************************************************************* +void +ScriptStorageManager::removeScriptDocURIHashEntry( const OUString & origURI ) +{ + StorageId_hash::iterator it = m_StorageIdOrigURIHash.find( origURI ); + if ( it == m_StorageIdOrigURIHash.end() ) + { + OSL_TRACE( "ScriptStorageManager::removeScriptDocURIHashEntry: no entry to remove" ); + return; + } + + // remove entry for this doc url from orig uri map. + m_StorageIdOrigURIHash.erase( it ); +} + +//******************************************************************* +void SAL_CALL +ScriptStorageManager::refreshScriptStorage( const OUString & stringURI ) +throw( RuntimeException ) +{ + OSL_TRACE( "** => ScriptStorageManager in refreshScriptStorage\n" ); + OSL_TRACE( "** => refreshing URI: %s\n", + ::rtl::OUStringToOString( + stringURI, RTL_TEXTENCODING_ASCII_US ).pData->buffer); + + sal_Int32 storageID = getScriptStorageID( stringURI ); + + if ( storageID == -1 ) + { + OSL_TRACE( "** id was -1, no storage"); + // Refreshing noexistent storage - just return + return; + } + + try + { + Reference < storage::XScriptStorageRefresh > xSSR( + getScriptStorage( storageID ), UNO_QUERY ); + + xSSR->refresh(); + } + catch ( RuntimeException & e ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::refreshScriptStorage: " ).concat( + e.Message ), Reference< XInterface >() ); + } + catch ( Exception & e ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::refreshScriptStorage: " ).concat( + e.Message ), Reference< XInterface >() ); + } +} + +//************************************************************************* +void SAL_CALL +ScriptStorageManager::checkPermission( const OUString & +scriptStorageURI, const OUString & permissionRequest ) +throw ( RuntimeException, lang::IllegalArgumentException, css::security::AccessControlException ) +{ + try + { + m_securityMgr.checkPermission( scriptStorageURI, permissionRequest ); + } + catch ( css::security::AccessControlException & e ) + { + throw css::security::AccessControlException( + OUSTR( "ScriptStorageManager::checkPermission: AccessControlException: " ).concat( + e.Message ), Reference< XInterface >(), e.LackingPermission ); + } + catch ( lang::IllegalArgumentException & e ) + { + throw lang::IllegalArgumentException( + OUSTR( "ScriptStorageManager::checkPermission: IllegalArgumentException: " ).concat( + e.Message ), Reference< XInterface >(), e.ArgumentPosition ); + } + catch ( RuntimeException & e ) + { + throw RuntimeException( + OUSTR( "ScriptStorageManager::checkPermission: RuntimeException: " ).concat( + e.Message ), Reference< XInterface >() ); + } +} + +//************************************************************************* +OUString SAL_CALL +ScriptStorageManager::getImplementationName( ) +throw( RuntimeException ) +{ + return s_implName; +} + +//************************************************************************* +sal_Bool SAL_CALL +ScriptStorageManager::supportsService( const OUString& serviceName ) +throw( RuntimeException ) +{ + OUString const * pNames = s_serviceNames.getConstArray(); + for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; ) + { + if ( serviceName.equals( pNames[ nPos ] ) ) + { + return sal_True; + } + } + return sal_False; +} + +//************************************************************************* +Sequence< OUString > SAL_CALL +ScriptStorageManager::getSupportedServiceNames( ) +throw( RuntimeException ) +{ + return s_serviceNames; +} + +//************************************************************************* +void SAL_CALL +ScriptStorageManager::disposing( const ::com::sun::star::lang::EventObject& Source ) +throw ( ::com::sun::star::uno::RuntimeException ) +{ + OSL_TRACE( "ScriptStorageManager::disposing started" ); + OSL_TRACE( "event object type=%s", + ::rtl::OUStringToOString( getCppuType( &Source ).getTypeName(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + OUString storageURI; + bool removeSecurityPermission = true; + try + { + Reference< XInterface > xInterface = Source.Source; + // no UNO_QUERY_THROW since we want a 2nd change to query if it's + // not a document being disposed + Reference< frame::XModel > xModel = Reference< frame::XModel > ( xInterface, UNO_QUERY ); + if( xModel.is() ) + { + storageURI = xModel->getURL(); + } + else + { + // UNO_QURY_THROW here since it's supposed to be either a doc + // or a XScriptInfo (in the case of a filesys script) + Reference< storage::XScriptInfo > xScriptInfo = Reference< storage::XScriptInfo > ( xInterface, UNO_QUERY_THROW ); + storageURI = xScriptInfo->getParcelURI().concat( xScriptInfo->getFunctionName() ); + // to save the user seeing the security dialogs every time they + // run the script we hang on to the permission for a given script + // for the lifetime of the Office + removeSecurityPermission = false; + // possibly need to encode it?? + } + if ( storageURI.getLength() > 0 ) + { + OSL_TRACE( "URI disposing is ... %s", + ::rtl::OUStringToOString( storageURI, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + } + } + catch ( RuntimeException& e ) + { + OUString message = + OUSTR( + "ScriptStorageManager::disposing: can't get script context, reason = " ); + message = message.concat( e.Message ); + OSL_TRACE( ::rtl::OUStringToOString( message, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + return; + } + + + // grab storage id. + sal_Int32 scriptStorageID = getScriptStorageID( storageURI ); + + // no need to do anything if there's no doc storage + if( scriptStorageID == -1 ) + { + return; + } + + OSL_TRACE( "disposing storageID = %d", scriptStorageID ); + + // attempt to get the storage from the hash to ensure that we have a + // valid storageID + ScriptStorage_map::const_iterator itr = + m_ScriptStorageMap.find( scriptStorageID ); + + if ( itr == m_ScriptStorageMap.end() ) + { + OSL_TRACE( "Entry for storage id %d doesn't exist in map", scriptStorageID ); + return; + } + + // erase the entry from the hash + m_ScriptStorageMap.erase( scriptStorageID ); + removeScriptDocURIHashEntry( storageURI ); + if ( removeSecurityPermission ) + { + m_securityMgr.removePermissionSettings ( storageURI ); + } +} +} // Namespace + +namespace scripting_runtimemgr +{ +//************************************************************************* +Reference< XInterface > SAL_CALL +ssm_create( + const Reference< XComponentContext > & xCompC ) +{ + return ( cppu::OWeakObject * ) new ::scripting_impl::ScriptStorageManager( xCompC ); +} + +//************************************************************************* +Sequence< OUString > +ssm_getSupportedServiceNames( ) +SAL_THROW( () ) +{ + return ::scripting_impl::s_serviceNames; +} + +//************************************************************************* +OUString +ssm_getImplementationName( ) +SAL_THROW( () ) +{ + return ::scripting_impl::s_implName; +} +} diff --git a/scripting/source/storage/ScriptStorageManager.hxx b/scripting/source/storage/ScriptStorageManager.hxx new file mode 100644 index 000000000000..2c2563971511 --- /dev/null +++ b/scripting/source/storage/ScriptStorageManager.hxx @@ -0,0 +1,225 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _DRAFTS_COM_SUN_STAR_SCRIPT_FRAMEWORK_STORAGE_SCRIPTSTORAGEMANAGER_HXX_ +#define _DRAFTS_COM_SUN_STAR_SCRIPT_FRAMEWORK_STORAGE_SCRIPTSTORAGEMANAGER_HXX_ + +#include <hash_map> +#include <map> + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase4.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/security/AccessControlException.hpp> +#include <com/sun/star/uno/RuntimeException.hpp> + +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptStorageRefresh.hpp> +#include <drafts/com/sun/star/script/framework/storage/XScriptInfo.hpp> +#include <drafts/com/sun/star/script/framework/security/XScriptSecurity.hpp> +#include "ScriptSecurityManager.hxx" + + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +// Define a map used to store the ScriptingStorages key;d by ID +typedef ::std::map < sal_Int32, css::uno::Reference < css::uno::XInterface > > + ScriptStorage_map; + +typedef ::std::hash_map < ::rtl::OUString, sal_Int32, ::rtl::OUStringHash> + StorageId_hash; + +class ScriptStorageManager : public + ::cppu::WeakImplHelper4 < dcsssf::storage::XScriptStorageManager, + dcsssf::security::XScriptSecurity, css::lang::XServiceInfo, + css::lang::XEventListener > +{ +public: + explicit ScriptStorageManager( + const css::uno::Reference< css::uno::XComponentContext > & xContext ) + SAL_THROW ( ( css::uno::RuntimeException ) ); + + + ~ScriptStorageManager() SAL_THROW ( () ); + + // XServiceInfo implementation + //====================================================================== + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw( css::uno::RuntimeException ); + //---------------------------------------------------------------------- + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw( css::uno::RuntimeException ); + //---------------------------------------------------------------------- + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw( css::uno::RuntimeException ); + //====================================================================== + + //XScriptStorageManager + //====================================================================== + /** + create a ScriptStorage using the XSimpleFileAccess passed as an + argument, and return a ID for getting the associated ScriptStorage + + @params xSFA + an implementation of XSimpleFileAccess that knows its own base URL + and can thus take URLs relative to that base. + + @returns an unsigned short ScriptStorage ID, which can be used in the + getScriptStorage method + */ + virtual sal_Int32 SAL_CALL createScriptStorage( + const css::uno::Reference< css::ucb::XSimpleFileAccess > & xSFA ) + throw ( css::uno::RuntimeException ); + //---------------------------------------------------------------------- + /** + create a ScriptStorage using the XSimpleFileAccess, and a string URL + and return a ID for getting the associated ScriptStorage + + @params xSFA + a standard implementation of XSimpleFileAccess + + @params stringURI + a string URI to the head of the script storage + + @returns an unsigned short ScriptStorage ID, which can be used in the + getScriptStorage method + */ + virtual sal_Int32 SAL_CALL + createScriptStorageWithURI( + const css::uno::Reference< css::ucb::XSimpleFileAccess >& xSFA, + const ::rtl::OUString& stringURI ) + throw ( css::uno::RuntimeException ); + //---------------------------------------------------------------------- + /** + get a ScriptStorage component using its scriptStorageID + + @params scriptStorageID + the usigned short returned by one of the methods above. ID=0 is + reserved for the application/share scripts, and ID=1 is reserved + for the application/user scripts + + @returns an XInterface to a component that implements the ScriptStorage + service + */ + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getScriptStorage( + sal_Int32 scriptStorageID ) + throw ( css::uno::RuntimeException ); + + /** + get a ScriptStorage ID using storage URI + + @param scriptStorageURI + the file URL for the document will retrieve storage id for the document, special treatment is reserved for the strings "USER"and "SHARE" which + retrieve storage id for application/user application/share areas respectively. + + + @returns as long ScriptStorage ID (-1 if no storage exists), which can be used in getScriptStorage method. + + */ + + virtual sal_Int32 SAL_CALL getScriptStorageID( const ::rtl::OUString& scriptStorageURI ) + throw (::com::sun::star::uno::RuntimeException); + + /** + refresh a storage component using its URI + + @param StringURI + URI of storage area, for documents, url to document eg, file:///home/user/ADocument.sxw To refresh the storage for user or share area, use USER or SHARE respectively instead or a url. + + */ + + virtual void SAL_CALL refreshScriptStorage(const ::rtl::OUString & stringURI) + throw ( css::uno::RuntimeException ); + //====================================================================== + + //XScriptSecurity + //====================================================================== + //---------------------------------------------------------------------- + /** + the language independent interface for invocation + + @param scriptURI + a string containing the script URI + + @returns + the value returned from the function being invoked + + @throws IllegalArgumentException + if there is no matching script name + + */ + virtual void SAL_CALL ScriptStorageManager::checkPermission( + const rtl::OUString & scriptStorageURI, + const rtl::OUString & permissionRequest ) + throw ( css::uno::RuntimeException, css::lang::IllegalArgumentException, + css::security::AccessControlException ); + //====================================================================== + + //XEventListener + //====================================================================== + + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) + throw ( css::uno::RuntimeException ); + +private: + ScriptStorageManager( const ScriptStorageManager & ); + ScriptStorageManager& operator= ( const ScriptStorageManager & ); + + void removeScriptDocURIHashEntry( const ::rtl::OUString & origURI ); + + // to obtain other services if needed + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::lang::XMultiComponentFactory > m_xMgr; + ::osl::Mutex m_mutex; + ScriptStorage_map m_ScriptStorageMap; + StorageId_hash m_StorageIdOrigURIHash; + sal_Int32 m_count; + scripting_securitymgr::ScriptSecurityManager m_securityMgr; + + void setupAppStorage( const css::uno::Reference< css::util::XMacroExpander > & xME, + const ::rtl::OUString & storageStr, + const ::rtl::OUString & appStr) + SAL_THROW ( ( css::uno::RuntimeException ) ); + + sal_Int32 setupAnyStorage( + const css::uno::Reference< css::ucb::XSimpleFileAccess> & xSFA, + const ::rtl::OUString & storageStr, + const ::rtl::OUString & origStringURI ) + SAL_THROW ( ( css::uno::RuntimeException ) ); + +}; +} // scripting_impl + +#endif //_COM_SUN_STAR_SCRIPTING_STORAGE_SCRIPTSTORAGEMANAGER_HXX_ diff --git a/scripting/source/storage/ScriptURI.cxx b/scripting/source/storage/ScriptURI.cxx new file mode 100644 index 000000000000..0b9159ec03af --- /dev/null +++ b/scripting/source/storage/ScriptURI.cxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <osl/diagnose.h> +#include <osl/file.h> + +#ifdef _DEBUG +#include <stdio.h> +#endif + +//Local headers +#include "ScriptURI.hxx" +#include <util/util.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + + +namespace scripting_impl { + +static const OUString schema = OUString::createFromAscii( "vnd.sun.star.script://" ); + +/** + * Constructor + * + * @param scriptURI the string script URI + */ +ScriptURI::ScriptURI( const ::rtl::OUString& scriptURI ) + throw ( IllegalArgumentException ) : m_uri( scriptURI ) +{ + OSL_TRACE( "received uri: %s\n",::rtl::OUStringToOString( m_uri, RTL_TEXTENCODING_ASCII_US).pData->buffer ); + set_values( parseIt() ); + if( !isValid() ) + { + OSL_TRACE( "ScriptURI ctor: throwing IllegalArgException" ); + throw IllegalArgumentException( + OUSTR( "Failed to parse invalid URI: " ).concat( scriptURI ), + Reference < XInterface > (), 1 ); + } +} + +/** + * Destuctor + * + */ +// dtor should never throw exceptions, so ensure this by specifying it +ScriptURI::~ScriptURI() SAL_THROW( () ) +{ + OSL_TRACE( "< ScriptURI dtor called >\n" ); +} + +/** + * This function is used to determine if this object represents a valid URI + * + */ +bool ScriptURI::isValid( ) { + return ( m_valid == sal_True ); +} + +/** + * This function returns the location of the script + * + */ +::rtl::OUString ScriptURI::getLocation( ) +{ + return m_location; +} + +/** + * This function returns the language of the script, eg. java, StarBasic,... + * + */ +::rtl::OUString ScriptURI::getLanguage( ) +{ + return m_language; +} + +/** + * This function returns the language dependent function name of the script + * + */ +::rtl::OUString ScriptURI::getFunctionName( ) +{ + return m_functionName; +} + +/** + * This function returns the language independent logical name of the script + * + */ +::rtl::OUString ScriptURI::getLogicalName( ) +{ + return m_logicalName; +} + +/** + * This function returns the full URI + * + */ +::rtl::OUString ScriptURI::getURI( ) +{ + return m_uri; +} + +//Private mutex guarded method for setting the members +void ScriptURI::set_values( scripting_impl::Uri values ) +{ + osl::Guard< ::osl::Mutex > aGuard( m_mutex ); + m_valid = values.valid; + m_location = values.location; + m_language = values.language; +// format is vnd.sun.star.script://[function_name]?language=[languge]&location=[location] +// LogicalName is now not used anymore, further more the ScriptURI class +// will be retired also and a new UNO service will be used. Additionally the +// parcel-description will also need to be modified to remove logical name +// In order to temporarly support the existing code functionname is +// set to the logica name parsed by this class. So getLogicalName() and +// getFunctionName() return identical string. +// + + m_functionName = values.logicalName; + m_logicalName = values.logicalName; + +} +/** + * This is a private method used for parsing the URI received by the + * initialization. + * + */ +// rather naive parsing? +Uri ScriptURI::parseIt() +{ + sal_Int32 schemaLen = schema.getLength(); + scripting_impl::Uri results; + results.valid = sal_True; + //attempt to parse + // check that it starts vnd.sun.star.script + // better check for OBO errors here + if( m_uri.indexOf( schema ) != 0 ) + { + OSL_TRACE( "wrong schema" ); + results.valid=sal_False; + return results; + } + + // substr from here to the '?' and set the logical name + sal_Int32 len = m_uri.indexOf( '?' ); + if( len == -1 ) + { + // no queries so just set the logical name + results.logicalName = m_uri.copy( schemaLen ); + return results; + } + results.logicalName = m_uri.copy( schemaLen, len-schemaLen ); + OSL_TRACE( "log name: %s\n", ::rtl::OUStringToOString( results.logicalName, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + len++; + // now get the attributes + OUString attr; + do + { + attr = m_uri.getToken( 0, '&', len ); + OSL_TRACE( "chunk: %s\n", ::rtl::OUStringToOString( attr, + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + if( attr.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "language" ) ) + == sal_True ) + { + sal_Int32 len2 = attr.indexOf('='); + results.language = attr.copy( len2 + 1 ); + continue; + } + else if ( attr.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "location" ) ) + == sal_True ) + { + sal_Int32 len2 = attr.indexOf( '=' ); + results.location = attr.copy( len2 + 1 ); + continue; + } + else if ( attr.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "function" ) ) + == sal_True ) + { + sal_Int32 len2 = attr.indexOf( '=' ); + results.functionName = attr.copy( len2 + 1 ); + continue; + } + else + { + OSL_TRACE( "Unknown attribute?\n" ); + } + } + while ( len >= 0 ); + + // parse is good + return results; +} + +} // namespace script_uri diff --git a/scripting/source/storage/ScriptURI.hxx b/scripting/source/storage/ScriptURI.hxx new file mode 100644 index 000000000000..d4387f5dee10 --- /dev/null +++ b/scripting/source/storage/ScriptURI.hxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_STORAGE_SCRIPTURI_HXX_ +#define __FRAMEWORK_STORAGE_SCRIPTURI_HXX_ + +#include <osl/mutex.hxx> +#include <rtl/ustring> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +namespace scripting_impl { +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +struct Uri { + bool valid; + ::rtl::OUString uri; + ::rtl::OUString location; + ::rtl::OUString language; + ::rtl::OUString functionName; + ::rtl::OUString logicalName; +}; +/** + * Helper class for dealing with script URIs. + */ +class ScriptURI +{ +public: + ScriptURI( const ::rtl::OUString& scriptURI ) + throw ( css::lang::IllegalArgumentException ); + virtual ~ScriptURI() SAL_THROW ( () ); + + /** + * This function returns the location of the script + * + */ + virtual ::rtl::OUString getLocation(); + + /** + * This function returns the language of the script, eg. java, + * StarBasic,... + * + */ + virtual ::rtl::OUString getLanguage(); + + /** + * This function returns the language dependent function name of + * the script + */ + virtual ::rtl::OUString getFunctionName(); + + /** + * This function returns the language independent logical name of + * the script + */ + virtual ::rtl::OUString getLogicalName(); + + /** + * This function returns the full URI + * + */ + virtual ::rtl::OUString getURI(); + +private: + ::osl::Mutex m_mutex; + + /** @internal */ + sal_Bool m_valid; + + //the private strings + /** the string representation of the this objects URI */ + ::rtl::OUString m_uri; + /** the location of the script referred to by this URI */ + ::rtl::OUString m_location; + /** the language of the script referred to by this URI */ + ::rtl::OUString m_language; + /** the language dependent function name of the script referred to by this URI */ + ::rtl::OUString m_functionName; + /** the language independent logical name of the script referred to by this URI */ + ::rtl::OUString m_logicalName; + + //attempt to parse the URI provided + /** @internal */ + Uri parseIt(); + //set the members + /** @internal */ + void set_values( Uri ); + bool isValid(); +} +; // class ScriptURI + +} //namespace script_uri + +#endif // define __FRAMEWORK_STORAGE_SCRIPTURI_HXX_ diff --git a/scripting/source/storage/XMLElement.cxx b/scripting/source/storage/XMLElement.cxx new file mode 100644 index 000000000000..0f8346476fc0 --- /dev/null +++ b/scripting/source/storage/XMLElement.cxx @@ -0,0 +1,169 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "XMLElement.hxx" +#include <osl/diagnose.h> + +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::uno; + +namespace scripting_impl +{ + +//************************************************************************* +void XMLElement::addAttribute( OUString const & rAttrName, OUString const & rValue ) +SAL_THROW( () ) +{ + OSL_TRACE( "XMLElement::addAttribute\n" ); + + _attrNames.push_back( rAttrName ); + _attrValues.push_back( rValue ); +} + +//************************************************************************* +void XMLElement::addSubElement( Reference< xml::sax::XAttributeList > const & xElem ) +SAL_THROW( () ) +{ + OSL_TRACE( "XMLElement::addSubElement\n" ); + + _subElems.push_back( xElem ); +} + +//************************************************************************* +Reference< xml::sax::XAttributeList > XMLElement::getSubElement( sal_Int32 nIndex ) +SAL_THROW( () ) +{ + OSL_TRACE( "XMLElement::getSubElement\n" ); + + return _subElems[ ( size_t )nIndex ]; +} + +//************************************************************************* +void XMLElement::dumpSubElements( Reference< xml::sax::XExtendedDocumentHandler > const & xOut ) +{ + OSL_TRACE( "+++++ XMLElement::dumpSubElement\n" ); + + for ( size_t nPos = 0; nPos < _subElems.size(); ++nPos ) + { + XMLElement * pElem = static_cast< XMLElement * >( _subElems[ nPos ].get() ); + pElem->dump( xOut ); + } +} + +//************************************************************************* +void XMLElement::dump( Reference< xml::sax::XExtendedDocumentHandler > const & xOut ) +{ + OSL_TRACE( "XMLElement::dump" ); + + xOut->ignorableWhitespace( OUString() ); + OSL_TRACE( "XMLElement::dump starting %s",::rtl::OUStringToOString( + _name, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + xOut->startElement( _name, static_cast< xml::sax::XAttributeList * >( this ) ); + // Write out CDATA + if( _chars.getLength() > 0 ) + { + xOut->ignorableWhitespace( OUString() ); + xOut->characters( _chars ); + } + // write sub elements + dumpSubElements( xOut ); + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( _name ); + OSL_TRACE( "XMLElement::dump ending %s",::rtl::OUStringToOString( + _name, RTL_TEXTENCODING_ASCII_US ).pData->buffer ); +} + +//************************************************************************* +// XAttributeList +sal_Int16 XMLElement::getLength() +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getLength\n" ); + + return _attrNames.size(); +} + +//************************************************************************* +OUString XMLElement::getNameByIndex( sal_Int16 nPos ) +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getNameByIndex\n" ); + OSL_ASSERT( ( size_t )nPos < _attrNames.size() ); + + return _attrNames[ nPos ]; +} + +//************************************************************************* +OUString XMLElement::getTypeByIndex( sal_Int16 nPos ) +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getTypeByIndex\n" ); + OSL_ASSERT( (size_t)nPos < _attrNames.size() ); + + // xxx todo + return OUString(); +} + +//************************************************************************* +OUString XMLElement::getTypeByName( OUString const & rName ) +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getTypeByName\n" ); + // xxx todo + return OUString(); +} + +//************************************************************************* +OUString XMLElement::getValueByIndex( sal_Int16 nPos ) +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getValueByIndex\n" ); + OSL_ASSERT( ( size_t )nPos < _attrNames.size() ); + + return _attrValues[ nPos ]; +} + +//************************************************************************* +OUString XMLElement::getValueByName( OUString const & rName ) +throw ( RuntimeException ) +{ + OSL_TRACE( "XMLElement::getValueByName\n" ); + + for ( size_t nPos = 0; nPos < _attrNames.size(); ++nPos ) + { + if (_attrNames[ nPos ] == rName) + { + return _attrValues[ nPos ]; + } + } + return OUString(); +} + +} diff --git a/scripting/source/storage/XMLElement.hxx b/scripting/source/storage/XMLElement.hxx new file mode 100644 index 000000000000..c5798454a556 --- /dev/null +++ b/scripting/source/storage/XMLElement.hxx @@ -0,0 +1,140 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SCRIPTING_XML_ELEMENT_HXX_ +#define _SCRIPTING_XML_ELEMENT_HXX_ + +#include <vector> + +#include <cppuhelper/implbase1.hxx> + +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +namespace scripting_impl +{ +// for simplification +#define css ::com::sun::star +#define dcsssf ::drafts::com::sun::star::script::framework + +/*################################################################################################## + + EXPORTING + +##################################################################################################*/ + +//================================================================================================== +class XMLElement : public ::cppu::WeakImplHelper1< css::xml::sax::XAttributeList > +{ +public: + inline XMLElement( ::rtl::OUString const & name, ::rtl::OUString const & chars ) + SAL_THROW( () ) + : _name( name ), _chars( chars ) + { + } + + inline XMLElement( ::rtl::OUString const & name ) + SAL_THROW( () ) + : _name( name ) + { + } + + /** Adds a sub element of element. + + @param xElem element reference + */ + void SAL_CALL addSubElement( + css::uno::Reference< css::xml::sax::XAttributeList > const & xElem ) + SAL_THROW( () ); + + /** Gets sub element of given index. The index follows order in which sub elements were added. + + @param nIndex index of sub element + */ + css::uno::Reference< css::xml::sax::XAttributeList > SAL_CALL getSubElement( + sal_Int32 nIndex ) + SAL_THROW( () ); + + /** Adds an attribute to elements. + + @param rAttrName qname of attribute + @param rValue value string of element + */ + void SAL_CALL addAttribute( ::rtl::OUString const & rAttrName, + ::rtl::OUString const & rValue ) + SAL_THROW( () ); + + /** Gets the tag name (qname) of element. + + @return + qname of element + */ + inline ::rtl::OUString SAL_CALL getName() SAL_THROW( () ) + { + return _name; + } + + /** Dumps out element (and all sub elements). + + @param xOut document handler to be written to + */ + void SAL_CALL dump( + css::uno::Reference< css::xml::sax::XExtendedDocumentHandler > const & xOut ); + /** Dumps out sub elements (and all further sub elements). + + @param xOut document handler to be written to + */ + void SAL_CALL dumpSubElements( + css::uno::Reference< css::xml::sax::XExtendedDocumentHandler > const & xOut ); + + // XAttributeList + virtual sal_Int16 SAL_CALL getLength() + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getNameByIndex( sal_Int16 nPos ) + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getTypeByIndex( sal_Int16 nPos ) + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getTypeByName( ::rtl::OUString const & rName ) + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getValueByIndex( sal_Int16 nPos ) + throw ( css::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getValueByName( ::rtl::OUString const & rName ) + throw ( css::uno::RuntimeException ); + +protected: + ::rtl::OUString _name; + + ::rtl::OUString _chars; + + ::std::vector< ::rtl::OUString > _attrNames; + ::std::vector< ::rtl::OUString > _attrValues; + + ::std::vector< css::uno::Reference< + css::xml::sax::XAttributeList > > _subElems; +}; + +} + +#endif diff --git a/scripting/source/storage/exports.dxp b/scripting/source/storage/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/scripting/source/storage/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/scripting/source/storage/makefile.mk b/scripting/source/storage/makefile.mk new file mode 100644 index 000000000000..7ba35edf0692 --- /dev/null +++ b/scripting/source/storage/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME= scripting +TARGET= storage +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=\ + $(SLO)$/ScriptURI.obj\ + $(SLO)$/ScriptStorage.obj\ + $(SLO)$/ScriptInfo.obj\ + $(SLO)$/ScriptMetadataImporter.obj\ + $(SLO)$/ScriptElement.obj\ + $(SLO)$/XMLElement.obj\ + $(SLO)$/ScriptStorageManager.obj\ + $(SLO)$/ScriptSecurityManager.obj\ + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/storage/storage.xml b/scripting/source/storage/storage.xml new file mode 100644 index 000000000000..6438dc7006b2 --- /dev/null +++ b/scripting/source/storage/storage.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name>storage</module-name> + <component-description> + <author></author> + <name>drafts.com.sun.star.script.framework.storage.ScriptStorage</name> + <description></description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="draft"/> + <supported-service>drafts.com.sun.star.script.framework.storage.ScriptingStorage</supported-service> + <type>com.sun.star.beans.XPropertySet</type> + <type>com.sun.star.beans.XPropertyContainer</type> + <type>com.sun.star.uno.Exception</type> + <type>com.sun.star.uno.XComponentContext</type> + <type>com.sun.star.uno.XWeak</type> + <type>com.sun.star.io.IOException</type> + <type>com.sun.star.io.XStream</type> + <type>com.sun.star.io.XOutputStream</type> + <type>com.sun.star.registry.XRegistryKey</type> + <type>drafts.com.sun.star.script.framework.storage.XScriptInfo</type> + <type>drafts.com.sun.star.script.framework.storage.XScriptInfoAccess</type> + <type>drafts.com.sun.star.script.framework.security.XScriptSecurity</type> + <type>drafts.com.sun.star.script.framework.storage.XScriptStorageExport</type> + <type>drafts.com.sun.star.script.framework.storage.XScriptStorageRefresh</type> + <type>com.sun.star.lang.XInitialization</type> + <type>drafts.com.sun.star.script.framework.storage.XScriptStorageManager</type> + <type>com.sun.star.xml.sax.XExtendedDocumentHandler</type> + <type>com.sun.star.xml.sax.XParser</type> + <type>com.sun.star.io.XInputStream</type> + <type>com.sun.star.ucb.XSimpleFileAccess2</type> + <type>com.sun.star.xml.sax.SAXException</type> + <type>com.sun.star.xml.sax.XAttributeList</type> + <type>com.sun.star.io.XActiveDataSource</type> + <type>com.sun.star.security.AccessControlException</type> + <type>com.sun.star.security.RuntimePermission</type> + <type>com.sun.star.lang.IllegalArgumentException</type> + </component-description> + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + <runtime-module-dependency>cppuhelper2$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu2</runtime-module-dependency> + <runtime-module-dependency>sal2</runtime-module-dependency> + <runtime-module-dependency>ucb</runtime-module-dependency> +</module-description> diff --git a/scripting/source/stringresource/makefile.mk b/scripting/source/stringresource/makefile.mk new file mode 100644 index 000000000000..dfc2d1979190 --- /dev/null +++ b/scripting/source/stringresource/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=scripting +TARGET=stringresource +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/stringresource.obj \ + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX).uno +SHL1IMPLIB= i$(TARGET) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +SHL1STDLIBS= \ + $(TOOLSLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/scripting/source/stringresource/stringresource.cxx b/scripting/source/stringresource/stringresource.cxx new file mode 100644 index 000000000000..58b6c21b522f --- /dev/null +++ b/scripting/source/stringresource/stringresource.cxx @@ -0,0 +1,3097 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "stringresource.hxx" +#include <com/sun/star/io/XTextInputStream.hpp> +#include <com/sun/star/io/XTextOutputStream.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ +#include <cppuhelper/implementationentry.hxx> +#endif +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> +#include <tools/urlobj.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::container; + + +//......................................................................... +namespace stringresource +{ +//......................................................................... + +// ============================================================================= +// mutex +// ============================================================================= + +::osl::Mutex& getMutex() +{ + static ::osl::Mutex* s_pMutex = 0; + if ( !s_pMutex ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !s_pMutex ) + { + static ::osl::Mutex s_aMutex; + s_pMutex = &s_aMutex; + } + } + return *s_pMutex; +} + + +// ============================================================================= +// StringResourceImpl +// ============================================================================= + +// component operations +static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceImpl() +{ + Sequence< ::rtl::OUString > names(1); + names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResource") ); + return names; +} + +static ::rtl::OUString getImplementationName_StringResourceImpl() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResource") ); +} + +static Reference< XInterface > SAL_CALL create_StringResourceImpl( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) +{ + return static_cast< ::cppu::OWeakObject * >( new StringResourcePersistenceImpl( xContext ) ); +} + + +// ============================================================================= + +StringResourceImpl::StringResourceImpl( const Reference< XComponentContext >& rxContext ) + : m_xContext( rxContext ) + , m_pCurrentLocaleItem( NULL ) + , m_pDefaultLocaleItem( NULL ) + , m_bDefaultModified( false ) + , m_aListenerContainer( getMutex() ) + , m_bModified( false ) + , m_bReadOnly( false ) + , m_nNextUniqueNumericId( UNIQUE_NUMBER_NEEDS_INITIALISATION ) +{ +} + +// ============================================================================= + +StringResourceImpl::~StringResourceImpl() +{ + for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + delete pLocaleItem; + } + + for( LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); it != m_aDeletedLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + delete pLocaleItem; + } +} + + +// ============================================================================= +// XServiceInfo + +::rtl::OUString StringResourceImpl::getImplementationName( ) throw (RuntimeException) +{ + return getImplementationName_StringResourceImpl(); +} + +sal_Bool StringResourceImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; +} + +Sequence< ::rtl::OUString > StringResourceImpl::getSupportedServiceNames( ) throw (RuntimeException) +{ + return getSupportedServiceNames_StringResourceImpl(); +} + + +// ============================================================================= +// XModifyBroadcaster + +void StringResourceImpl::addModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + if( !aListener.is() ) + throw RuntimeException(); + + ::osl::MutexGuard aGuard( getMutex() ); + Reference< XInterface > xIface( aListener, UNO_QUERY ); + m_aListenerContainer.addInterface( xIface ); +} + +void StringResourceImpl::removeModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + if( !aListener.is() ) + throw RuntimeException(); + + ::osl::MutexGuard aGuard( getMutex() ); + Reference< XInterface > xIface( aListener, UNO_QUERY ); + m_aListenerContainer.removeInterface( xIface ); +} + + +// ============================================================================= +// XStringResourceResolver + +::rtl::OUString StringResourceImpl::implResolveString + ( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ) + throw (::com::sun::star::resource::MissingResourceException) +{ + ::rtl::OUString aRetStr; + bool bSuccess = false; + if( pLocaleItem != NULL && loadLocale( pLocaleItem ) ) + { + IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID ); + if( !( it == pLocaleItem->m_aIdToStringMap.end() ) ) + { + aRetStr = (*it).second; + bSuccess = true; + } + } + if( !bSuccess ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: No entry for ResourceID: " ); + errorMsg.concat( ResourceID ); + throw ::com::sun::star::resource::MissingResourceException( errorMsg, Reference< XInterface >() ); + } + return aRetStr; +} + +::rtl::OUString StringResourceImpl::resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return implResolveString( ResourceID, m_pCurrentLocaleItem ); +} + +::rtl::OUString StringResourceImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + LocaleItem* pLocaleItem = getItemForLocale( locale, false ); + return implResolveString( ResourceID, pLocaleItem ); +} + +sal_Bool StringResourceImpl::implHasEntryForId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ) +{ + bool bSuccess = false; + if( pLocaleItem != NULL && loadLocale( pLocaleItem ) ) + { + IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID ); + if( !( it == pLocaleItem->m_aIdToStringMap.end() ) ) + bSuccess = true; + } + return bSuccess; +} + +sal_Bool StringResourceImpl::hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return implHasEntryForId( ResourceID, m_pCurrentLocaleItem ); +} + +sal_Bool StringResourceImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const Locale& locale ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + LocaleItem* pLocaleItem = getItemForLocale( locale, false ); + return implHasEntryForId( ResourceID, pLocaleItem ); +} + +Sequence< ::rtl::OUString > StringResourceImpl::implGetResourceIDs( LocaleItem* pLocaleItem ) +{ + Sequence< ::rtl::OUString > aIDSeq( 0 ); + if( pLocaleItem && loadLocale( pLocaleItem ) ) + { + const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap; + sal_Int32 nResourceIDCount = rHashMap.size(); + aIDSeq.realloc( nResourceIDCount ); + ::rtl::OUString* pStrings = aIDSeq.getArray(); + + IdToStringMap::const_iterator it; + int iTarget = 0; + for( it = rHashMap.begin(); it != rHashMap.end(); it++ ) + { + ::rtl::OUString aStr = (*it).first; + pStrings[iTarget] = aStr; + iTarget++; + } + } + return aIDSeq; +} + +Sequence< ::rtl::OUString > StringResourceImpl::getResourceIDsForLocale + ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + LocaleItem* pLocaleItem = getItemForLocale( locale, false ); + return implGetResourceIDs( pLocaleItem ); +} + +Sequence< ::rtl::OUString > StringResourceImpl::getResourceIDs( ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return implGetResourceIDs( m_pCurrentLocaleItem ); +} + +Locale StringResourceImpl::getCurrentLocale() + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + Locale aRetLocale; + if( m_pCurrentLocaleItem != NULL ) + aRetLocale = m_pCurrentLocaleItem->m_locale; + return aRetLocale; +} + +Locale StringResourceImpl::getDefaultLocale( ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + Locale aRetLocale; + if( m_pDefaultLocaleItem != NULL ) + aRetLocale = m_pDefaultLocaleItem->m_locale; + return aRetLocale; +} + +Sequence< Locale > StringResourceImpl::getLocales( ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + sal_Int32 nSize = m_aLocaleItemVector.size(); + Sequence< Locale > aLocalSeq( nSize ); + Locale* pLocales = aLocalSeq.getArray(); + int iTarget = 0; + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + pLocales[iTarget] = pLocaleItem->m_locale; + iTarget++; + } + return aLocalSeq; +} + + +// ============================================================================= +// XStringResourceManager + +void StringResourceImpl::implCheckReadOnly( const sal_Char* pExceptionMsg ) + throw (NoSupportException) +{ + if( m_bReadOnly ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( pExceptionMsg ); + throw NoSupportException( errorMsg, Reference< XInterface >() ); + } +} + +sal_Bool StringResourceImpl::isReadOnly() + throw (RuntimeException) +{ + return m_bReadOnly; +} + +void StringResourceImpl::implSetCurrentLocale( const Locale& locale, + sal_Bool FindClosestMatch, sal_Bool bUseDefaultIfNoMatch ) + throw (IllegalArgumentException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + LocaleItem* pLocaleItem = NULL; + if( FindClosestMatch ) + pLocaleItem = getClosestMatchItemForLocale( locale ); + else + pLocaleItem = getItemForLocale( locale, true ); + + if( pLocaleItem == NULL && bUseDefaultIfNoMatch ) + pLocaleItem = m_pDefaultLocaleItem; + + if( pLocaleItem != NULL ) + { + loadLocale( pLocaleItem ); + m_pCurrentLocaleItem = pLocaleItem; + + // Only notify without modifying + implNotifyListeners(); + } +} + +void StringResourceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch ) + throw (IllegalArgumentException, RuntimeException) +{ + sal_Bool bUseDefaultIfNoMatch = false; + implSetCurrentLocale( locale, FindClosestMatch, bUseDefaultIfNoMatch ); +} + +void StringResourceImpl::setDefaultLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException,NoSupportException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::setDefaultLocale(): Read only" ); + + LocaleItem* pLocaleItem = getItemForLocale( locale, true ); + if( pLocaleItem && pLocaleItem != m_pDefaultLocaleItem ) + { + if( m_pDefaultLocaleItem ) + { + LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale ); + m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem ); + } + + m_pDefaultLocaleItem = pLocaleItem; + m_bDefaultModified = true; + implModified(); + } +} + +void StringResourceImpl::implSetString( const ::rtl::OUString& ResourceID, + const ::rtl::OUString& Str, LocaleItem* pLocaleItem ) +{ + if( pLocaleItem != NULL && loadLocale( pLocaleItem ) ) + { + IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap; + + IdToStringMap::iterator it = rHashMap.find( ResourceID ); + bool bNew = ( it == rHashMap.end() ); + if( bNew ) + { + IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap; + rIndexMap[ ResourceID ] = pLocaleItem->m_nNextIndex++; + implScanIdForNumber( ResourceID ); + } + rHashMap[ ResourceID ] = Str; + pLocaleItem->m_bModified = true; + implModified(); + } +} + +void StringResourceImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (NoSupportException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::setString(): Read only" ); + implSetString( ResourceID, Str, m_pCurrentLocaleItem ); +} + +void StringResourceImpl::setStringForLocale + ( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale ) + throw (NoSupportException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::setStringForLocale(): Read only" ); + LocaleItem* pLocaleItem = getItemForLocale( locale, false ); + implSetString( ResourceID, Str, pLocaleItem ); +} + +void StringResourceImpl::implRemoveId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ) + throw (::com::sun::star::resource::MissingResourceException) +{ + if( pLocaleItem != NULL && loadLocale( pLocaleItem ) ) + { + IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap; + IdToStringMap::iterator it = rHashMap.find( ResourceID ); + if( it == rHashMap.end() ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: No entries for ResourceID: " ); + errorMsg.concat( ResourceID ); + throw ::com::sun::star::resource::MissingResourceException( errorMsg, Reference< XInterface >() ); + } + rHashMap.erase( it ); + pLocaleItem->m_bModified = true; + implModified(); + } +} + +void StringResourceImpl::removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::removeId(): Read only" ); + implRemoveId( ResourceID, m_pCurrentLocaleItem ); +} + +void StringResourceImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::removeIdForLocale(): Read only" ); + LocaleItem* pLocaleItem = getItemForLocale( locale, false ); + implRemoveId( ResourceID, pLocaleItem ); +} + +void StringResourceImpl::newLocale( const Locale& locale ) + throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::newLocale(): Read only" ); + + if( getItemForLocale( locale, false ) != NULL ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: locale already exists" ); + throw ElementExistException( errorMsg, Reference< XInterface >() ); + } + + // TODO?: Check if locale is valid? How? + bool bValid = true; + if( bValid ) + { + LocaleItem* pLocaleItem = new LocaleItem( locale ); + m_aLocaleItemVector.push_back( pLocaleItem ); + pLocaleItem->m_bModified = true; + + // Copy strings from default locale + LocaleItem* pCopyFromItem = m_pDefaultLocaleItem; + if( pCopyFromItem == NULL ) + pCopyFromItem = m_pCurrentLocaleItem; + if( pCopyFromItem != NULL && loadLocale( pCopyFromItem ) ) + { + const IdToStringMap& rSourceMap = pCopyFromItem->m_aIdToStringMap; + IdToStringMap& rTargetMap = pLocaleItem->m_aIdToStringMap; + IdToStringMap::const_iterator it; + for( it = rSourceMap.begin(); it != rSourceMap.end(); it++ ) + { + ::rtl::OUString aId = (*it).first; + ::rtl::OUString aStr = (*it).second; + rTargetMap[ aId ] = aStr; + } + + const IdToIndexMap& rSourceIndexMap = pCopyFromItem->m_aIdToIndexMap; + IdToIndexMap& rTargetIndexMap = pLocaleItem->m_aIdToIndexMap; + IdToIndexMap::const_iterator it_index; + for( it_index = rSourceIndexMap.begin(); it_index != rSourceIndexMap.end(); it_index++ ) + { + ::rtl::OUString aId = (*it_index).first; + sal_Int32 nIndex = (*it_index).second; + rTargetIndexMap[ aId ] = nIndex; + } + pLocaleItem->m_nNextIndex = pCopyFromItem->m_nNextIndex; + } + + if( m_pCurrentLocaleItem == NULL ) + m_pCurrentLocaleItem = pLocaleItem; + + if( m_pDefaultLocaleItem == NULL ) + { + m_pDefaultLocaleItem = pLocaleItem; + m_bDefaultModified = true; + } + + implModified(); + } + else + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: Invalid locale" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } +} + +void StringResourceImpl::removeLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException, NoSupportException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceImpl::removeLocale(): Read only" ); + + LocaleItem* pRemoveItem = getItemForLocale( locale, true ); + if( pRemoveItem ) + { + // Last locale? + sal_Int32 nLocaleCount = m_aLocaleItemVector.size(); + if( nLocaleCount > 1 ) + { + LocaleItem* pFallbackItem = NULL; + if( m_pCurrentLocaleItem == pRemoveItem || + m_pDefaultLocaleItem == pRemoveItem ) + { + for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != pRemoveItem ) + { + pFallbackItem = pLocaleItem; + break; + } + } + if( m_pCurrentLocaleItem == pRemoveItem ) + { + sal_Bool FindClosestMatch = false; + setCurrentLocale( pFallbackItem->m_locale, FindClosestMatch ); + } + if( m_pDefaultLocaleItem == pRemoveItem ) + { + setDefaultLocale( pFallbackItem->m_locale ); + } + } + } + for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem == pRemoveItem ) + { + // Remember locale item to delete file while storing + m_aDeletedLocaleItemVector.push_back( pLocaleItem ); + + // Last locale? + if( nLocaleCount == 1 ) + { + m_nNextUniqueNumericId = 0; + if( m_pDefaultLocaleItem ) + { + LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale ); + m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem ); + } + m_pCurrentLocaleItem = NULL; + m_pDefaultLocaleItem = NULL; + } + + m_aLocaleItemVector.erase( it ); + + implModified(); + break; + } + } + } +} + +void StringResourceImpl::implScanIdForNumber( const ::rtl::OUString& ResourceID ) +{ + const sal_Unicode* pSrc = ResourceID.getStr(); + sal_Int32 nLen = ResourceID.getLength(); + + sal_Int32 nNumber = 0; + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + sal_Unicode c = pSrc[i]; + if( c >= '0' && c <= '9' ) + { + sal_uInt16 nDigitVal = c - '0'; + nNumber = 10*nNumber + nDigitVal; + } + else + break; + } + + if( m_nNextUniqueNumericId < nNumber + 1 ) + m_nNextUniqueNumericId = nNumber + 1; +} + +sal_Int32 StringResourceImpl::getUniqueNumericId( ) + throw (RuntimeException, NoSupportException) +{ + if( m_nNextUniqueNumericId == UNIQUE_NUMBER_NEEDS_INITIALISATION ) + { + implLoadAllLocales(); + m_nNextUniqueNumericId = 0; + } + + if( m_nNextUniqueNumericId < UNIQUE_NUMBER_NEEDS_INITIALISATION ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "getUniqueNumericId: Extended sal_Int32 range" ); + throw NoSupportException( errorMsg, Reference< XInterface >() ); + } + return m_nNextUniqueNumericId; +} + + +// ============================================================================= +// Private helper methods + +LocaleItem* StringResourceImpl::getItemForLocale + ( const Locale& locale, sal_Bool bException ) + throw (::com::sun::star::lang::IllegalArgumentException) +{ + LocaleItem* pRetItem = NULL; + + // Search for locale + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem ) + { + Locale& cmp_locale = pLocaleItem->m_locale; + if( cmp_locale.Language == locale.Language && + cmp_locale.Country == locale.Country && + cmp_locale.Variant == locale.Variant ) + { + pRetItem = pLocaleItem; + break; + } + } + } + + if( pRetItem == NULL && bException ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: Invalid locale" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } + return pRetItem; +} + +// Returns the LocalItem for a given locale, if it exists, otherwise NULL +// This method performes a closest match search, at least the language must match +LocaleItem* StringResourceImpl::getClosestMatchItemForLocale( const Locale& locale ) +{ + LocaleItem* pRetItem = NULL; + + // Search for locale + for( sal_Int32 iPass = 0 ; iPass <= 2 ; ++iPass ) + { + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem ) + { + Locale& cmp_locale = pLocaleItem->m_locale; + if( cmp_locale.Language == locale.Language && + (iPass > 1 || cmp_locale.Country == locale.Country) && + (iPass > 0 || cmp_locale.Variant == locale.Variant) ) + { + pRetItem = pLocaleItem; + break; + } + } + } + if( pRetItem ) + break; + } + + return pRetItem; +} + +void StringResourceImpl::implModified( void ) +{ + m_bModified = true; + implNotifyListeners(); +} + +void StringResourceImpl::implNotifyListeners( void ) +{ + EventObject aEvent; + aEvent.Source = static_cast< XInterface* >( (OWeakObject*)this ); + + ::cppu::OInterfaceIteratorHelper it( m_aListenerContainer ); + while( it.hasMoreElements() ) + { + Reference< XInterface > xIface = it.next(); + Reference< XModifyListener > xListener( xIface, UNO_QUERY ); + try + { + xListener->modified( aEvent ); + } + catch(RuntimeException&) + { + it.remove(); + } + } +} + + +// ============================================================================= +// Loading + +bool StringResourceImpl::loadLocale( LocaleItem* pLocaleItem ) +{ + // Base implementation has nothing to load + (void)pLocaleItem; + return true; +} + +void StringResourceImpl::implLoadAllLocales( void ) +{ + // Base implementation has nothing to load +} + + +Reference< XMultiComponentFactory > StringResourceImpl::getMultiComponentFactory( void ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + if( !m_xMCF.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + if( !xSMgr.is() ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringResourceImpl::getMultiComponentFactory: Couldn't instantiate MultiComponentFactory" ) ), + Reference< XInterface >() ); + } + m_xMCF = xSMgr; + } + return m_xMCF; +} + + +// ============================================================================= +// StringResourcePersistenceImpl +// ============================================================================= + +StringResourcePersistenceImpl::StringResourcePersistenceImpl( const Reference< XComponentContext >& rxContext ) + : StringResourcePersistenceImpl_BASE( rxContext ) +{ +} + +// ----------------------------------------------------------------------------- + +StringResourcePersistenceImpl::~StringResourcePersistenceImpl() +{ +} + +// ----------------------------------------------------------------------------- +// XServiceInfo +// ----------------------------------------------------------------------------- + +::rtl::OUString StringResourcePersistenceImpl::getImplementationName( ) + throw (RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM + ( "com.sun.star.comp.scripting.StringResourceWithLocation") ); +} + +// ----------------------------------------------------------------------------- + +sal_Bool StringResourcePersistenceImpl::supportsService( const ::rtl::OUString& rServiceName ) + throw (RuntimeException) +{ + return StringResourceImpl::supportsService( rServiceName ); +} + +// ----------------------------------------------------------------------------- + +Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getSupportedServiceNames( ) + throw (RuntimeException) +{ + return StringResourceImpl::getSupportedServiceNames(); +} + +// ----------------------------------------------------------------------------- +// XInitialization base functionality for derived classes +// ----------------------------------------------------------------------------- + +static ::rtl::OUString aNameBaseDefaultStr = ::rtl::OUString::createFromAscii( "strings" ); + +void StringResourcePersistenceImpl::implInitializeCommonParameters + ( const Sequence< Any >& aArguments ) + throw (Exception, RuntimeException) +{ + bool bReadOnlyOk = (aArguments[1] >>= m_bReadOnly); + if( !bReadOnlyOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected ReadOnly flag" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 1 ); + } + + com::sun::star::lang::Locale aCurrentLocale; + bool bLocaleOk = (aArguments[2] >>= aCurrentLocale); + if( !bLocaleOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected Locale" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 2 ); + } + + bool bNameBaseOk = (aArguments[3] >>= m_aNameBase); + if( !bNameBaseOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected NameBase string" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 3 ); + } + if( m_aNameBase.getLength() == 0 ) + m_aNameBase = aNameBaseDefaultStr; + + bool bCommentOk = (aArguments[4] >>= m_aComment); + if( !bCommentOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected Comment string" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 4 ); + } + + implScanLocales(); + + sal_Bool FindClosestMatch = true; + sal_Bool bUseDefaultIfNoMatch = true; + implSetCurrentLocale( aCurrentLocale, FindClosestMatch, bUseDefaultIfNoMatch ); +} + +// ----------------------------------------------------------------------------- +// Forwarding calls to base class + +// XModifyBroadcaster +void StringResourcePersistenceImpl::addModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::addModifyListener( aListener ); +} +void StringResourcePersistenceImpl::removeModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::removeModifyListener( aListener ); +} + +// XStringResourceResolver +::rtl::OUString StringResourcePersistenceImpl::resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveString( ResourceID ) ; +} +::rtl::OUString StringResourcePersistenceImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveStringForLocale( ResourceID, locale ); +} +sal_Bool StringResourcePersistenceImpl::hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForId( ResourceID ) ; +} +sal_Bool StringResourcePersistenceImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const Locale& locale ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale ); +} +Locale StringResourcePersistenceImpl::getCurrentLocale() + throw (RuntimeException) +{ + return StringResourceImpl::getCurrentLocale(); +} +Locale StringResourcePersistenceImpl::getDefaultLocale( ) + throw (RuntimeException) +{ + return StringResourceImpl::getDefaultLocale(); +} +Sequence< Locale > StringResourcePersistenceImpl::getLocales( ) + throw (RuntimeException) +{ + return StringResourceImpl::getLocales(); +} + +// XStringResourceManager +sal_Bool StringResourcePersistenceImpl::isReadOnly() + throw (RuntimeException) +{ + return StringResourceImpl::isReadOnly(); +} +void StringResourcePersistenceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch ) + throw (IllegalArgumentException, RuntimeException) +{ + StringResourceImpl::setCurrentLocale( locale, FindClosestMatch ); +} +void StringResourcePersistenceImpl::setDefaultLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException,NoSupportException) +{ + StringResourceImpl::setDefaultLocale( locale ); +} +Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getResourceIDs( ) + throw (RuntimeException) +{ + return StringResourceImpl::getResourceIDs(); +} +void StringResourcePersistenceImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setString( ResourceID, Str ); +} +void StringResourcePersistenceImpl::setStringForLocale + ( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setStringForLocale( ResourceID, Str, locale ); +} +Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getResourceIDsForLocale + ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException) +{ + return StringResourceImpl::getResourceIDsForLocale( locale ); +} +void StringResourcePersistenceImpl::removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeId( ResourceID ); +} +void StringResourcePersistenceImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeIdForLocale( ResourceID, locale ); +} +void StringResourcePersistenceImpl::newLocale( const Locale& locale ) + throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::newLocale( locale ); +} +void StringResourcePersistenceImpl::removeLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeLocale( locale ); +} +sal_Int32 StringResourcePersistenceImpl::getUniqueNumericId( ) + throw (RuntimeException, NoSupportException) +{ + return StringResourceImpl::getUniqueNumericId(); +} + +// ----------------------------------------------------------------------------- +// XStringResourcePersistence + +void StringResourcePersistenceImpl::store() + throw (NoSupportException, Exception, RuntimeException) +{ +} + +sal_Bool StringResourcePersistenceImpl::isModified( ) + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + return m_bModified; +} + +void StringResourcePersistenceImpl::setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException) +{ + m_aComment = Comment; +} + +void StringResourcePersistenceImpl::storeToStorage( const Reference< XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + bool bUsedForStore = false; + bool bStoreAll = true; + implStoreAtStorage( NameBase, Comment, Storage, bUsedForStore, bStoreAll ); +} + +void StringResourcePersistenceImpl::implStoreAtStorage +( + const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aComment, + const Reference< ::com::sun::star::embed::XStorage >& Storage, + bool bUsedForStore, + bool bStoreAll +) + throw (Exception, RuntimeException) +{ + // Delete files for deleted locales + if( bUsedForStore ) + { + while( m_aDeletedLocaleItemVector.size() > 0 ) + { + LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL ) + { + ::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase ); + aStreamName += ::rtl::OUString::createFromAscii( ".properties" ); + + try + { + Storage->removeElement( aStreamName ); + } + catch( Exception& ) + {} + + m_aDeletedLocaleItemVector.erase( it ); + delete pLocaleItem; + } + } + } + + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL && (bStoreAll || pLocaleItem->m_bModified) && + loadLocale( pLocaleItem ) ) + { + ::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase ); + aStreamName += ::rtl::OUString::createFromAscii( ".properties" ); + + Reference< io::XStream > xElementStream = + Storage->openStreamElement( aStreamName, ElementModes::READWRITE ); + + ::rtl::OUString aPropName = ::rtl::OUString::createFromAscii( "MediaType" ); + ::rtl::OUString aMime = ::rtl::OUString::createFromAscii( "text/plain" ); + + uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY ); + OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" ); + if ( xProps.is() ) + { + xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) ); + + aPropName = ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" ); + xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) ); + } + + Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream(); + if( xOutputStream.is() ) + implWritePropertiesFile( pLocaleItem, xOutputStream, aComment ); + xOutputStream->closeOutput(); + + if( bUsedForStore ) + pLocaleItem->m_bModified = false; + } + } + + // Delete files for changed defaults + if( bUsedForStore ) + { + for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin(); + it != m_aChangedDefaultLocaleVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL ) + { + ::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase ); + aStreamName += ::rtl::OUString::createFromAscii( ".default" ); + + try + { + Storage->removeElement( aStreamName ); + } + catch( Exception& ) + {} + + delete pLocaleItem; + } + } + m_aChangedDefaultLocaleVector.clear(); + } + + // Default locale + if( m_pDefaultLocaleItem != NULL && (bStoreAll || m_bDefaultModified) ) + { + ::rtl::OUString aStreamName = implGetFileNameForLocaleItem( m_pDefaultLocaleItem, aNameBase ); + aStreamName += ::rtl::OUString::createFromAscii( ".default" ); + + Reference< io::XStream > xElementStream = + Storage->openStreamElement( aStreamName, ElementModes::READWRITE ); + + ::rtl::OUString aPropName = ::rtl::OUString::createFromAscii( "MediaType" ); + ::rtl::OUString aMime = ::rtl::OUString::createFromAscii( "text/plain" ); + + // Only create stream without content + Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream(); + xOutputStream->closeOutput(); + + if( bUsedForStore ) + m_bDefaultModified = false; + } +} + +void StringResourcePersistenceImpl::storeToURL( const ::rtl::OUString& URL, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment, + const Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + bool bUsedForStore = false; + bool bStoreAll = true; + + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + Reference< ucb::XSimpleFileAccess > xFileAccess; + xFileAccess = Reference< ucb::XSimpleFileAccess >( xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY ); + if( xFileAccess.is() && Handler.is() ) + xFileAccess->setInteractionHandler( Handler ); + + implStoreAtLocation( URL, NameBase, Comment, xFileAccess, bUsedForStore, bStoreAll ); +} + +void StringResourcePersistenceImpl::implKillRemovedLocaleFiles +( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess +) + throw (Exception, RuntimeException) +{ + // Delete files for deleted locales + while( m_aDeletedLocaleItemVector.size() > 0 ) + { + LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL ) + { + ::rtl::OUString aCompleteFileName = + implGetPathForLocaleItem( pLocaleItem, aNameBase, Location ); + if( xFileAccess->exists( aCompleteFileName ) ) + xFileAccess->kill( aCompleteFileName ); + + m_aDeletedLocaleItemVector.erase( it ); + delete pLocaleItem; + } + } +} + +void StringResourcePersistenceImpl::implKillChangedDefaultFiles +( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess +) + throw (Exception, RuntimeException) +{ + // Delete files for changed defaults + for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin(); + it != m_aChangedDefaultLocaleVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL ) + { + ::rtl::OUString aCompleteFileName = + implGetPathForLocaleItem( pLocaleItem, aNameBase, Location, true ); + if( xFileAccess->exists( aCompleteFileName ) ) + xFileAccess->kill( aCompleteFileName ); + + delete pLocaleItem; + } + } + m_aChangedDefaultLocaleVector.clear(); +} + +void StringResourcePersistenceImpl::implStoreAtLocation +( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aComment, + const Reference< ucb::XSimpleFileAccess >& xFileAccess, + bool bUsedForStore, + bool bStoreAll, + bool bKillAll +) + throw (Exception, RuntimeException) +{ + // Delete files for deleted locales + if( bUsedForStore || bKillAll ) + implKillRemovedLocaleFiles( Location, aNameBase, xFileAccess ); + + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL && (bStoreAll || bKillAll || pLocaleItem->m_bModified) && + loadLocale( pLocaleItem ) ) + { + ::rtl::OUString aCompleteFileName = + implGetPathForLocaleItem( pLocaleItem, aNameBase, Location ); + if( xFileAccess->exists( aCompleteFileName ) ) + xFileAccess->kill( aCompleteFileName ); + + if( !bKillAll ) + { + // Create Output stream + Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName ); + if( xOutputStream.is() ) + { + implWritePropertiesFile( pLocaleItem, xOutputStream, aComment ); + xOutputStream->closeOutput(); + } + if( bUsedForStore ) + pLocaleItem->m_bModified = false; + } + } + } + + // Delete files for changed defaults + if( bUsedForStore || bKillAll ) + implKillChangedDefaultFiles( Location, aNameBase, xFileAccess ); + + // Default locale + if( m_pDefaultLocaleItem != NULL && (bStoreAll || bKillAll || m_bDefaultModified) ) + { + ::rtl::OUString aCompleteFileName = + implGetPathForLocaleItem( m_pDefaultLocaleItem, aNameBase, Location, true ); + if( xFileAccess->exists( aCompleteFileName ) ) + xFileAccess->kill( aCompleteFileName ); + + if( !bKillAll ) + { + // Create Output stream + Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName ); + if( xOutputStream.is() ) + xOutputStream->closeOutput(); + + if( bUsedForStore ) + m_bDefaultModified = false; + } + } +} + + +// ----------------------------------------------------------------------------- +// BinaryOutput, helper class for exportBinary + +class BinaryOutput +{ + Reference< XMultiComponentFactory > m_xMCF; + Reference< XComponentContext > m_xContext; + Reference< XInterface > m_xTempFile; + Reference< io::XOutputStream > m_xOutputStream; + +public: + BinaryOutput( Reference< XMultiComponentFactory > xMCF, + Reference< XComponentContext > xContext ); + + Reference< io::XOutputStream > getOutputStream( void ) + { return m_xOutputStream; } + + Sequence< ::sal_Int8 > closeAndGetData( void ); + + // Template to be used with sal_Int16 and sal_Unicode + template< class T > + void write16BitInt( T n ); + void writeInt16( sal_Int16 n ) + { write16BitInt( n ); } + void writeUnicodeChar( sal_Unicode n ) + { write16BitInt( n ); } + void writeInt32( sal_Int32 n ); + void writeString( const ::rtl::OUString& aStr ); +}; + +BinaryOutput::BinaryOutput( Reference< XMultiComponentFactory > xMCF, + Reference< XComponentContext > xContext ) + : m_xMCF( xMCF ) + , m_xContext( xContext ) +{ + m_xTempFile = m_xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ), m_xContext ); + if( m_xTempFile.is() ) + m_xOutputStream = Reference< io::XOutputStream >( m_xTempFile, UNO_QUERY ); +} + +template< class T > +void BinaryOutput::write16BitInt( T n ) +{ + if( !m_xOutputStream.is() ) + return; + + Sequence< sal_Int8 > aSeq( 2 ); + sal_Int8* p = aSeq.getArray(); + + sal_Int8 nLow = sal_Int8( n & 0xff ); + sal_Int8 nHigh = sal_Int8( n >> 8 ); + + p[0] = nLow; + p[1] = nHigh; + m_xOutputStream->writeBytes( aSeq ); +} + +void BinaryOutput::writeInt32( sal_Int32 n ) +{ + if( !m_xOutputStream.is() ) + return; + + Sequence< sal_Int8 > aSeq( 4 ); + sal_Int8* p = aSeq.getArray(); + + for( sal_Int16 i = 0 ; i < 4 ; i++ ) + { + p[i] = sal_Int8( n & 0xff ); + n >>= 8; + } + m_xOutputStream->writeBytes( aSeq ); +} + +void BinaryOutput::writeString( const ::rtl::OUString& aStr ) +{ + sal_Int32 nLen = aStr.getLength(); + const sal_Unicode* pStr = aStr.getStr(); + + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + writeUnicodeChar( pStr[i] ); + + writeUnicodeChar( 0 ); +} + +Sequence< ::sal_Int8 > BinaryOutput::closeAndGetData( void ) +{ + Sequence< ::sal_Int8 > aRetSeq; + if( !m_xOutputStream.is() ) + return aRetSeq; + + m_xOutputStream->closeOutput(); + + Reference< io::XSeekable> xSeekable( m_xTempFile, UNO_QUERY ); + if( !xSeekable.is() ) + return aRetSeq; + + sal_Int32 nSize = (sal_Int32)xSeekable->getPosition(); + + Reference< io::XInputStream> xInputStream( m_xTempFile, UNO_QUERY ); + if( !xInputStream.is() ) + return aRetSeq; + + xSeekable->seek( 0 ); + sal_Int32 nRead = xInputStream->readBytes( aRetSeq, nSize ); + (void)nRead; + OSL_ENSURE( nRead == nSize, "BinaryOutput::closeAndGetData: nRead != nSize" ); + + return aRetSeq; +} + + +// Binary format: + +// Header +// Byte Content +// 0 + 1 sal_Int16: Version, currently 0, low byte first +// 2 + 3 sal_Int16: Locale count = n, low byte first +// 4 + 5 sal_Int16: Default Locale position in Locale list, == n if none +// 6 - 7 sal_Int32: Start index locale block 0, lowest byte first +// (n-1) * sal_Int32: Start index locale block 1 to n, lowest byte first +// 6 + 4*n sal_Int32: "Start index" non existing locale block n+1, +// marks the first invalid index, kind of EOF + +// Locale block +// All strings are stored as 2-Byte-0 terminated sequence +// of 16 bit Unicode characters, each with low byte first +// Empty strings only contain the 2-Byte-0 + +// Members of com.sun.star.lang.Locale +// with l1 = Locale.Language.getLength() +// with l2 = Locale.Country.getLength() +// with l3 = Locale.Variant.getLength() +// pos0 = 0 Locale.Language +// pos1 = 2 * (l1 + 1) Locale.Country +// pos2 = pos1 + 2 * (l2 + 1) Locale.Variant +// pos3 = pos2 + 2 * (l3 + 1) +// pos3 Properties file written by implWritePropertiesFile + +Sequence< sal_Int8 > StringResourcePersistenceImpl::exportBinary( ) + throw (RuntimeException) +{ + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + BinaryOutput aOut( xMCF, m_xContext ); + + sal_Int32 nLocaleCount = m_aLocaleItemVector.size(); + Sequence< sal_Int8 >* pLocaleDataSeq = new Sequence< sal_Int8 >[ nLocaleCount ]; + + sal_Int32 iLocale = 0; + sal_Int32 iDefault = 0; + for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); + it != m_aLocaleItemVector.end(); it++,iLocale++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL && loadLocale( pLocaleItem ) ) + { + if( m_pDefaultLocaleItem == pLocaleItem ) + iDefault = iLocale; + + BinaryOutput aLocaleOut( m_xMCF, m_xContext ); + implWriteLocaleBinary( pLocaleItem, aLocaleOut ); + + pLocaleDataSeq[iLocale] = aLocaleOut.closeAndGetData(); + } + } + + // Write header + sal_Int16 nVersion = 0; + sal_Int16 nLocaleCount16 = (sal_Int16)nLocaleCount; + sal_Int16 iDefault16 = (sal_Int16)iDefault; + aOut.writeInt16( nVersion ); + aOut.writeInt16( nLocaleCount16 ); + aOut.writeInt16( iDefault16 ); + + // Write data positions + sal_Int32 nDataPos = 6 + 4 * (nLocaleCount + 1); + for( iLocale = 0; iLocale < nLocaleCount; iLocale++ ) + { + aOut.writeInt32( nDataPos ); + + Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale]; + sal_Int32 nSeqLen = rSeq.getLength(); + nDataPos += nSeqLen; + } + // Write final position + aOut.writeInt32( nDataPos ); + + // Write data + Reference< io::XOutputStream > xOutputStream = aOut.getOutputStream(); + if( xOutputStream.is() ) + { + for( iLocale = 0; iLocale < nLocaleCount; iLocale++ ) + { + Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale]; + xOutputStream->writeBytes( rSeq ); + } + } + + delete[] pLocaleDataSeq; + + Sequence< sal_Int8 > aRetSeq = aOut.closeAndGetData(); + return aRetSeq; +} + +void StringResourcePersistenceImpl::implWriteLocaleBinary + ( LocaleItem* pLocaleItem, BinaryOutput& rOut ) +{ + Reference< io::XOutputStream > xOutputStream = rOut.getOutputStream(); + if( !xOutputStream.is() ) + return; + + Locale& rLocale = pLocaleItem->m_locale; + rOut.writeString( rLocale.Language ); + rOut.writeString( rLocale.Country ); + rOut.writeString( rLocale.Variant ); + implWritePropertiesFile( pLocaleItem, xOutputStream, m_aComment ); +} + +// ----------------------------------------------------------------------------- +// BinaryOutput, helper class for exportBinary + +class BinaryInput +{ + Sequence< sal_Int8 > m_aData; + Reference< XMultiComponentFactory > m_xMCF; + Reference< XComponentContext > m_xContext; + + const sal_Int8* m_pData; + sal_Int32 m_nCurPos; + sal_Int32 m_nSize; + +public: + BinaryInput( Sequence< ::sal_Int8 > aData, Reference< XMultiComponentFactory > xMCF, + Reference< XComponentContext > xContext ); + + Reference< io::XInputStream > getInputStreamForSection( sal_Int32 nSize ); + + void seek( sal_Int32 nPos ); + sal_Int32 getPosition( void ) + { return m_nCurPos; } + + sal_Int16 readInt16( void ); + sal_Int32 readInt32( void ); + sal_Unicode readUnicodeChar( void ); + ::rtl::OUString readString( void ); +}; + +BinaryInput::BinaryInput( Sequence< ::sal_Int8 > aData, Reference< XMultiComponentFactory > xMCF, + Reference< XComponentContext > xContext ) + : m_aData( aData ) + , m_xMCF( xMCF ) + , m_xContext( xContext ) +{ + m_pData = m_aData.getConstArray(); + m_nCurPos = 0; + m_nSize = m_aData.getLength(); +} + +Reference< io::XInputStream > BinaryInput::getInputStreamForSection( sal_Int32 nSize ) +{ + Reference< io::XInputStream > xIn; + if( m_nCurPos + nSize <= m_nSize ) + { + Reference< io::XOutputStream > xTempOut( m_xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ), m_xContext ), UNO_QUERY ); + if( xTempOut.is() ) + { + Sequence< sal_Int8 > aSection( m_pData + m_nCurPos, nSize ); + xTempOut->writeBytes( aSection ); + + Reference< io::XSeekable> xSeekable( xTempOut, UNO_QUERY ); + if( xSeekable.is() ) + xSeekable->seek( 0 ); + + xIn = Reference< io::XInputStream>( xTempOut, UNO_QUERY ); + } + } + else + OSL_ENSURE( false, "BinaryInput::getInputStreamForSection(): Read past end" ); + + return xIn; +} + +void BinaryInput::seek( sal_Int32 nPos ) +{ + if( nPos <= m_nSize ) + m_nCurPos = nPos; + else + OSL_ENSURE( false, "BinaryInput::seek(): Position past end" ); +} + + +sal_Int16 BinaryInput::readInt16( void ) +{ + sal_Int16 nRet = 0; + if( m_nCurPos + 2 <= m_nSize ) + { + nRet = nRet + sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) ); + nRet += 256 * sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) ); + } + else + OSL_ENSURE( false, "BinaryInput::readInt16(): Read past end" ); + + return nRet; +} + +sal_Int32 BinaryInput::readInt32( void ) +{ + sal_Int32 nRet = 0; + if( m_nCurPos + 4 <= m_nSize ) + { + sal_Int32 nFactor = 1; + for( sal_Int16 i = 0; i < 4; i++ ) + { + nRet += sal_uInt8( m_pData[m_nCurPos++] ) * nFactor; + nFactor *= 256; + } + } + else + OSL_ENSURE( false, "BinaryInput::readInt32(): Read past end" ); + + return nRet; +} + +sal_Unicode BinaryInput::readUnicodeChar( void ) +{ + sal_uInt16 nRet = 0; + if( m_nCurPos + 2 <= m_nSize ) + { + nRet = nRet + sal_uInt8( m_pData[m_nCurPos++] ); + nRet += 256 * sal_uInt8( m_pData[m_nCurPos++] ); + } + else + OSL_ENSURE( false, "BinaryInput::readUnicodeChar(): Read past end" ); + + sal_Unicode cRet = nRet; + return cRet; +} + +::rtl::OUString BinaryInput::readString( void ) +{ + ::rtl::OUStringBuffer aBuf; + sal_Unicode c; + do + { + c = readUnicodeChar(); + if( c != 0 ) + aBuf.append( c ); + } + while( c != 0 ); + + ::rtl::OUString aRetStr = aBuf.makeStringAndClear(); + return aRetStr; +} + +void StringResourcePersistenceImpl::importBinary( const Sequence< ::sal_Int8 >& Data ) + throw (IllegalArgumentException, RuntimeException) +{ + // Init: Remove all locales + sal_Int32 nOldLocaleCount = 0; + do + { + Sequence< Locale > aLocaleSeq = getLocales(); + nOldLocaleCount = aLocaleSeq.getLength(); + if( nOldLocaleCount > 0 ) + { + Locale aLocale = aLocaleSeq[0]; + removeLocale( aLocale ); + } + } + while( nOldLocaleCount > 0 ); + + // Import data + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + BinaryInput aIn( Data, xMCF, m_xContext ); + + sal_Int32 nVersion = aIn.readInt16(); + (void)nVersion; + sal_Int32 nLocaleCount = aIn.readInt16(); + sal_Int32 iDefault = aIn.readInt16(); + (void)iDefault; + + sal_Int32* pPositions = new sal_Int32[nLocaleCount + 1]; + for( sal_Int32 i = 0; i < nLocaleCount + 1; i++ ) + pPositions[i] = aIn.readInt32(); + + // Import locales + LocaleItem* pUseAsDefaultItem = NULL; + for( sal_Int32 i = 0; i < nLocaleCount; i++ ) + { + sal_Int32 nPos = pPositions[i]; + aIn.seek( nPos ); + + Locale aLocale; + aLocale.Language = aIn.readString(); + aLocale.Country = aIn.readString(); + aLocale.Variant = aIn.readString(); + + sal_Int32 nAfterStringPos = aIn.getPosition(); + sal_Int32 nSize = pPositions[i+1] - nAfterStringPos; + Reference< io::XInputStream > xInput = aIn.getInputStreamForSection( nSize ); + if( xInput.is() ) + { + LocaleItem* pLocaleItem = new LocaleItem( aLocale ); + if( iDefault == i ) + pUseAsDefaultItem = pLocaleItem; + m_aLocaleItemVector.push_back( pLocaleItem ); + implReadPropertiesFile( pLocaleItem, xInput ); + } + } + + if( pUseAsDefaultItem != NULL ) + setDefaultLocale( pUseAsDefaultItem->m_locale ); + + delete[] pPositions; +} + + +// ============================================================================= +// Private helper methods + +bool checkNamingSceme( const ::rtl::OUString& aName, const ::rtl::OUString& aNameBase, + Locale& aLocale ) +{ + bool bSuccess = false; + + sal_Int32 nNameLen = aName.getLength(); + sal_Int32 nNameBaseLen = aNameBase.getLength(); + + // Name has to start with NameBase followed + // by a '_' and at least one more character + if( aName.indexOf( aNameBase ) == 0 && nNameBaseLen < nNameLen-1 && + aName.getStr()[nNameBaseLen] == '_' ) + { + bSuccess = true; + + sal_Int32 iStart = nNameBaseLen + 1; + sal_Int32 iNext_ = aName.indexOf( '_', iStart ); + if( iNext_ != -1 && iNext_ < nNameLen-1 ) + { + aLocale.Language = aName.copy( iStart, iNext_ - iStart ); + + iStart = iNext_ + 1; + iNext_ = aName.indexOf( '_', iStart ); + if( iNext_ != -1 && iNext_ < nNameLen-1 ) + { + aLocale.Country = aName.copy( iStart, iNext_ - iStart ); + aLocale.Variant = aName.copy( iNext_ + 1 ); + } + else + aLocale.Country = aName.copy( iStart ); + } + else + aLocale.Language = aName.copy( iStart ); + } + return bSuccess; +} + +void StringResourcePersistenceImpl::implLoadAllLocales( void ) +{ + for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ ) + { + LocaleItem* pLocaleItem = *it; + if( pLocaleItem != NULL ) + loadLocale( pLocaleItem ); + } +} + +// Scan locale properties files helper +void StringResourcePersistenceImpl::implScanLocaleNames( const Sequence< ::rtl::OUString >& aContentSeq ) +{ + Locale aDefaultLocale; + bool bDefaultFound = false; + + sal_Int32 nCount = aContentSeq.getLength(); + const ::rtl::OUString* pFiles = aContentSeq.getConstArray(); + for( int i = 0 ; i < nCount ; i++ ) + { + ::rtl::OUString aCompleteName = pFiles[i]; + rtl::OUString aPureName; + rtl::OUString aExtension; + sal_Int32 iDot = aCompleteName.lastIndexOf( '.' ); + sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' ); + if( iDot != -1 ) + { + sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0; + aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom ); + aExtension = aCompleteName.copy( iDot + 1 ); + } + + if( aExtension.equalsAscii( "properties" ) ) + { + //rtl::OUString aName = aInetObj.getBase(); + Locale aLocale; + + if( checkNamingSceme( aPureName, m_aNameBase, aLocale ) ) + { + LocaleItem* pLocaleItem = new LocaleItem( aLocale, false ); + m_aLocaleItemVector.push_back( pLocaleItem ); + + if( m_pCurrentLocaleItem == NULL ) + m_pCurrentLocaleItem = pLocaleItem; + + if( m_pDefaultLocaleItem == NULL ) + { + m_pDefaultLocaleItem = pLocaleItem; + m_bDefaultModified = true; + } + } + } + else if( !bDefaultFound && aExtension.equalsAscii( "default" ) ) + { + //rtl::OUString aName = aInetObj.getBase(); + Locale aLocale; + + if( checkNamingSceme( aPureName, m_aNameBase, aDefaultLocale ) ) + bDefaultFound = true; + } + } + if( bDefaultFound ) + { + LocaleItem* pLocaleItem = getItemForLocale( aDefaultLocale, false ); + if( pLocaleItem ) + { + m_pDefaultLocaleItem = pLocaleItem; + m_bDefaultModified = false; + } + } +} + +// Scan locale properties files +void StringResourcePersistenceImpl::implScanLocales( void ) +{ + // Dummy implementation, method not called for this + // base class, but pure virtual not possible- +} + +bool StringResourcePersistenceImpl::loadLocale( LocaleItem* pLocaleItem ) +{ + bool bSuccess = false; + + OSL_ENSURE( pLocaleItem, "StringResourcePersistenceImpl::loadLocale(): pLocaleItem == NULL" ); + if( pLocaleItem ) + { + if( pLocaleItem->m_bLoaded ) + { + bSuccess = true; + } + else + { + bSuccess = implLoadLocale( pLocaleItem ); + pLocaleItem->m_bLoaded = true; // = bSuccess??? -> leads to more tries + } + } + return bSuccess; +} + +bool StringResourcePersistenceImpl::implLoadLocale( LocaleItem* ) +{ + // Dummy implementation, method not called for this + // base class, but pure virtual not possible- + return false; +} + +::rtl::OUString implGetNameScemeForLocaleItem( const LocaleItem* pLocaleItem ) +{ + static ::rtl::OUString aUnder = ::rtl::OUString::createFromAscii( "_" ); + + OSL_ENSURE( pLocaleItem, + "StringResourcePersistenceImpl::implGetNameScemeForLocaleItem(): pLocaleItem == NULL" ); + Locale aLocale = pLocaleItem->m_locale; + + ::rtl::OUString aRetStr = aUnder; + aRetStr += aLocale.Language; + + ::rtl::OUString aCountry = aLocale.Country; + if( aCountry.getLength() ) + { + aRetStr += aUnder; + aRetStr += aCountry; + } + + ::rtl::OUString aVariant = aLocale.Variant; + if( aVariant.getLength() ) + { + aRetStr += aUnder; + aRetStr += aVariant; + } + return aRetStr; +} + +::rtl::OUString StringResourcePersistenceImpl::implGetFileNameForLocaleItem + ( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase ) +{ + ::rtl::OUString aFileName = aNameBase; + if( aFileName.getLength() == 0 ) + aFileName = aNameBaseDefaultStr; + + aFileName += implGetNameScemeForLocaleItem( pLocaleItem ); + return aFileName; +} + +::rtl::OUString StringResourcePersistenceImpl::implGetPathForLocaleItem + ( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aLocation, bool bDefaultFile ) +{ + ::rtl::OUString aFileName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase ); + INetURLObject aInetObj( aLocation ); + aInetObj.insertName( aFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL ); + if( bDefaultFile ) + aInetObj.setExtension( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("default") ) ); + else + aInetObj.setExtension( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("properties") ) ); + ::rtl::OUString aCompleteFileName = aInetObj.GetMainURL( INetURLObject::NO_DECODE ); + return aCompleteFileName; +} + +// White space according to Java property files specification in +// http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream) +inline bool isWhiteSpace( sal_Unicode c ) +{ + bool bWhite = ( c == 0x0020 || // space + c == 0x0009 || // tab + c == 0x000a || // line feed, not always handled by TextInputStream + c == 0x000d || // carriage return, not always handled by TextInputStream + c == 0x000C ); // form feed + return bWhite; +} + +inline void skipWhites( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri ) +{ + while( ri < nLen ) + { + if( !isWhiteSpace( pBuf[ri] ) ) + break; + ri++; + } +} + +inline bool isHexDigit( sal_Unicode c, sal_uInt16& nDigitVal ) +{ + bool bRet = true; + if( c >= '0' && c <= '9' ) + nDigitVal = c - '0'; + else if( c >= 'a' && c <= 'f' ) + nDigitVal = c - 'a' + 10; + else if( c >= 'A' && c <= 'F' ) + nDigitVal = c - 'A' + 10; + else + bRet = false; + return bRet; +} + +sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri ) +{ + sal_Int32 i = ri; + + sal_Unicode cRet = 0; + sal_Unicode c = pBuf[i]; + switch( c ) + { + case 't': + cRet = 0x0009; + break; + case 'n': + cRet = 0x000a; + break; + case 'f': + cRet = 0x000c; + break; + case 'r': + cRet = 0x000d; + break; + case '\\': + cRet = '\\'; + break; + case 'u': + { + // Skip multiple u + i++; + while( i < nLen && pBuf[i] == 'u' ) + i++; + + // Process hex digits + sal_Int32 nDigitCount = 0; + sal_uInt16 nDigitVal; + while( i < nLen && isHexDigit( pBuf[i], nDigitVal ) ) + { + cRet = 16 * cRet + nDigitVal; + + nDigitCount++; + if( nDigitCount == 4 ) + { + // Write back position + ri = i; + break; + } + i++; + } + break; + } + default: + cRet = c; + } + + return cRet; +} + +void CheckContinueInNextLine( Reference< io::XTextInputStream > xTextInputStream, + ::rtl::OUString& aLine, bool& bEscapePending, const sal_Unicode*& pBuf, + sal_Int32& nLen, sal_Int32& i ) +{ + if( i == nLen && bEscapePending ) + { + bEscapePending = false; + + if( !xTextInputStream->isEOF() ) + { + aLine = xTextInputStream->readLine(); + nLen = aLine.getLength(); + pBuf = aLine.getStr(); + i = 0; + + skipWhites( pBuf, nLen, i ); + } + } +} + +bool StringResourcePersistenceImpl::implReadPropertiesFile + ( LocaleItem* pLocaleItem, const Reference< io::XInputStream >& xInputStream ) +{ + if( !xInputStream.is() || pLocaleItem == NULL ) + return false; + + bool bSuccess = false; + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + Reference< io::XTextInputStream > xTextInputStream( xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TextInputStream" ), m_xContext ), UNO_QUERY ); + + if( xTextInputStream.is() ) + { + Reference< io::XActiveDataSink> xActiveDataSink( xTextInputStream, UNO_QUERY ); + if( xActiveDataSink.is() ) + { + bSuccess = true; + + xActiveDataSink->setInputStream( xInputStream ); + + ::rtl::OUString aEncodingStr = ::rtl::OUString::createFromAscii + ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) ); + xTextInputStream->setEncoding( aEncodingStr ); + + ::rtl::OUString aLine; + while( !xTextInputStream->isEOF() ) + { + aLine = xTextInputStream->readLine(); + + sal_Int32 nLen = aLine.getLength(); + if( 0 == nLen ) + continue; + const sal_Unicode* pBuf = aLine.getStr(); + ::rtl::OUStringBuffer aBuf; + sal_Unicode c = 0; + sal_Int32 i = 0; + + skipWhites( pBuf, nLen, i ); + if( i == nLen ) + continue; // line contains only white spaces + + // Comment? + c = pBuf[i]; + if( c == '#' || c == '!' ) + continue; + + // Scan key + ::rtl::OUString aResourceID; + bool bEscapePending = false; + bool bStrComplete = false; + while( i < nLen && !bStrComplete ) + { + c = pBuf[i]; + if( bEscapePending ) + { + aBuf.append( getEscapeChar( pBuf, nLen, i ) ); + bEscapePending = false; + } + else + { + if( c == '\\' ) + { + bEscapePending = true; + } + else + { + if( c == ':' || c == '=' || isWhiteSpace( c ) ) + bStrComplete = true; + else + aBuf.append( c ); + } + } + i++; + + CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i ); + if( i == nLen ) + bStrComplete = true; + + if( bStrComplete ) + aResourceID = aBuf.makeStringAndClear(); + } + + // Ignore lines with empty keys + if( 0 == aResourceID.getLength() ) + continue; + + // Scan value + skipWhites( pBuf, nLen, i ); + + ::rtl::OUString aValueStr; + bEscapePending = false; + bStrComplete = false; + while( i < nLen && !bStrComplete ) + { + c = pBuf[i]; + if( c == 0x000a || c == 0x000d ) // line feed/carriage return, not always handled by TextInputStream + { + i++; + } + else + { + if( bEscapePending ) + { + aBuf.append( getEscapeChar( pBuf, nLen, i ) ); + bEscapePending = false; + } + else if( c == '\\' ) + bEscapePending = true; + else + aBuf.append( c ); + i++; + + CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i ); + } + if( i == nLen ) + bStrComplete = true; + + if( bStrComplete ) + aValueStr = aBuf.makeStringAndClear(); + } + + // Push into table + pLocaleItem->m_aIdToStringMap[ aResourceID ] = aValueStr; + implScanIdForNumber( aResourceID ); + IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap; + rIndexMap[ aResourceID ] = pLocaleItem->m_nNextIndex++; + } + } + } + + return bSuccess; +} + + +inline sal_Unicode getHexCharForDigit( sal_uInt16 nDigitVal ) +{ + sal_Unicode cRet = ( nDigitVal < 10 ) ? ('0' + nDigitVal) : ('a' + (nDigitVal-10)); + return cRet; +} + +void implWriteCharToBuffer( ::rtl::OUStringBuffer& aBuf, sal_Unicode cu, bool bKey ) +{ + if( cu == '\\' ) + { + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)'\\' ); + } + else if( cu == 0x000a ) + { + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)'n' ); + } + else if( cu == 0x000d ) + { + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)'r' ); + } + else if( bKey && cu == '=' ) + { + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)'=' ); + } + else if( bKey && cu == ':' ) + { + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)':' ); + } + // ISO/IEC 8859-1 range according to: + // http://en.wikipedia.org/wiki/ISO/IEC_8859-1 + else if( (cu >= 0x20 && cu <= 0x7e) ) + //TODO: Check why (cu >= 0xa0 && cu <= 0xFF) + //is encoded in sample properties files + //else if( (cu >= 0x20 && cu <= 0x7e) || + // (cu >= 0xa0 && cu <= 0xFF) ) + { + aBuf.append( cu ); + } + else + { + // Unicode encoding + aBuf.append( (sal_Unicode)'\\' ); + aBuf.append( (sal_Unicode)'u' ); + + sal_uInt16 nVal = cu; + for( sal_uInt16 i = 0 ; i < 4 ; i++ ) + { + sal_uInt16 nDigit = nVal / 0x1000; + nVal -= nDigit * 0x1000; + nVal *= 0x10; + aBuf.append( getHexCharForDigit( nDigit ) ); + } + } +} + +void implWriteStringWithEncoding( const ::rtl::OUString& aStr, + Reference< io::XTextOutputStream > xTextOutputStream, bool bKey ) +{ + static sal_Unicode cLineFeed = 0xa; + + (void)aStr; + (void)xTextOutputStream; + + ::rtl::OUStringBuffer aBuf; + sal_Int32 nLen = aStr.getLength(); + const sal_Unicode* pSrc = aStr.getStr(); + for( sal_Int32 i = 0 ; i < nLen ; i++ ) + { + sal_Unicode cu = pSrc[i]; + implWriteCharToBuffer( aBuf, cu, bKey ); + // TODO?: split long lines + } + if( !bKey ) + aBuf.append( cLineFeed ); + + ::rtl::OUString aWriteStr = aBuf.makeStringAndClear(); + xTextOutputStream->writeString( aWriteStr ); +} + +bool StringResourcePersistenceImpl::implWritePropertiesFile( LocaleItem* pLocaleItem, + const Reference< io::XOutputStream >& xOutputStream, const ::rtl::OUString& aComment ) +{ + static ::rtl::OUString aAssignmentStr = ::rtl::OUString::createFromAscii( "=" ); + static ::rtl::OUString aLineFeedStr = ::rtl::OUString::createFromAscii( "\n" ); + + if( !xOutputStream.is() || pLocaleItem == NULL ) + return false; + + bool bSuccess = false; + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + Reference< io::XTextOutputStream > xTextOutputStream( xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TextOutputStream" ), m_xContext ), UNO_QUERY ); + + if( xTextOutputStream.is() ) + { + Reference< io::XActiveDataSource> xActiveDataSource( xTextOutputStream, UNO_QUERY ); + if( xActiveDataSource.is() ) + { + xActiveDataSource->setOutputStream( xOutputStream ); + + ::rtl::OUString aEncodingStr = ::rtl::OUString::createFromAscii + ( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) ); + xTextOutputStream->setEncoding( aEncodingStr ); + + xTextOutputStream->writeString( aComment ); + xTextOutputStream->writeString( aLineFeedStr ); + + const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap; + if( rHashMap.size() > 0 ) + { + // Sort ids according to read order + const IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap; + IdToIndexMap::const_iterator it_index; + + // Find max/min index + sal_Int32 nMinIndex = -1; + sal_Int32 nMaxIndex = -1; + for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); it_index++ ) + { + sal_Int32 nIndex = (*it_index).second; + if( nMinIndex > nIndex || nMinIndex == -1 ) + nMinIndex = nIndex; + if( nMaxIndex < nIndex ) + nMaxIndex = nIndex; + } + sal_Int32 nTabSize = nMaxIndex - nMinIndex + 1; + + // Create sorted array of pointers to the id strings + const ::rtl::OUString** pIdPtrs = new const ::rtl::OUString*[nTabSize]; + sal_Int32 i; + for( i = 0 ; i < nTabSize ; i++ ) + pIdPtrs[i] = NULL; + for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); it_index++ ) + { + sal_Int32 nIndex = (*it_index).second; + pIdPtrs[nIndex - nMinIndex] = &((*it_index).first); + } + + // Write lines in correct order + for( i = 0 ; i < nTabSize ; i++ ) + { + const ::rtl::OUString* pStr = pIdPtrs[i]; + if( pStr != NULL ) + { + ::rtl::OUString aResourceID = *pStr; + IdToStringMap::const_iterator it = rHashMap.find( aResourceID ); + if( !( it == rHashMap.end() ) ) + { + implWriteStringWithEncoding( aResourceID, xTextOutputStream, true ); + xTextOutputStream->writeString( aAssignmentStr ); + ::rtl::OUString aValStr = (*it).second; + implWriteStringWithEncoding( aValStr, xTextOutputStream, false ); + } + } + } + + delete pIdPtrs; + } + + bSuccess = true; + } + } + return bSuccess; +} + + +// ============================================================================= +// StringResourceWithStorageImpl +// ============================================================================= + +// component operations +static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceWithStorageImpl() +{ + Sequence< ::rtl::OUString > names(1); + names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithStorage") ); + return names; +} + +static ::rtl::OUString getImplementationName_StringResourceWithStorageImpl() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResourceWithStorage") ); +} + +static Reference< XInterface > SAL_CALL create_StringResourceWithStorageImpl( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) +{ + return static_cast< ::cppu::OWeakObject * >( new StringResourceWithStorageImpl( xContext ) ); +} + +// ----------------------------------------------------------------------------- + +StringResourceWithStorageImpl::StringResourceWithStorageImpl( const Reference< XComponentContext >& rxContext ) + : StringResourceWithStorageImpl_BASE( rxContext ) + , m_bStorageChanged( false ) +{ +} + +// ----------------------------------------------------------------------------- + +StringResourceWithStorageImpl::~StringResourceWithStorageImpl() +{ +} + +// ----------------------------------------------------------------------------- +// XServiceInfo +// ----------------------------------------------------------------------------- + +::rtl::OUString StringResourceWithStorageImpl::getImplementationName( ) throw (RuntimeException) +{ + return getImplementationName_StringResourceWithStorageImpl(); +} + +// ----------------------------------------------------------------------------- + +sal_Bool StringResourceWithStorageImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; +} + +// ----------------------------------------------------------------------------- + +Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getSupportedServiceNames( ) throw (RuntimeException) +{ + return getSupportedServiceNames_StringResourceWithStorageImpl(); +} + +// ----------------------------------------------------------------------------- +// XInitialization +// ----------------------------------------------------------------------------- + +void StringResourceWithStorageImpl::initialize( const Sequence< Any >& aArguments ) + throw (Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + if ( aArguments.getLength() != 5 ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringResourceWithStorageImpl::initialize: invalid number of arguments!" ) ), + Reference< XInterface >() ); + } + + bool bOk = (aArguments[0] >>= m_xStorage); + if( bOk && !m_xStorage.is() ) + bOk = false; + + if( !bOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceWithStorageImpl::initialize: invalid storage" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } + + implInitializeCommonParameters( aArguments ); +} + +// ----------------------------------------------------------------------------- +// Forwarding calls to base class + +// XModifyBroadcaster +void StringResourceWithStorageImpl::addModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::addModifyListener( aListener ); +} +void StringResourceWithStorageImpl::removeModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::removeModifyListener( aListener ); +} + +// XStringResourceResolver +::rtl::OUString StringResourceWithStorageImpl::resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveString( ResourceID ) ; +} +::rtl::OUString StringResourceWithStorageImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveStringForLocale( ResourceID, locale ); +} +sal_Bool StringResourceWithStorageImpl::hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForId( ResourceID ) ; +} +sal_Bool StringResourceWithStorageImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const Locale& locale ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale ); +} +Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getResourceIDs( ) + throw (RuntimeException) +{ + return StringResourceImpl::getResourceIDs(); +} +Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getResourceIDsForLocale + ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException) +{ + return StringResourceImpl::getResourceIDsForLocale( locale ); +} +Locale StringResourceWithStorageImpl::getCurrentLocale() + throw (RuntimeException) +{ + return StringResourceImpl::getCurrentLocale(); +} +Locale StringResourceWithStorageImpl::getDefaultLocale( ) + throw (RuntimeException) +{ + return StringResourceImpl::getDefaultLocale(); +} +Sequence< Locale > StringResourceWithStorageImpl::getLocales( ) + throw (RuntimeException) +{ + return StringResourceImpl::getLocales(); +} + +// XStringResourceManager +sal_Bool StringResourceWithStorageImpl::isReadOnly() + throw (RuntimeException) +{ + return StringResourceImpl::isReadOnly(); +} +void StringResourceWithStorageImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch ) + throw (IllegalArgumentException, RuntimeException) +{ + StringResourceImpl::setCurrentLocale( locale, FindClosestMatch ); +} +void StringResourceWithStorageImpl::setDefaultLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException,NoSupportException) +{ + StringResourceImpl::setDefaultLocale( locale ); +} +void StringResourceWithStorageImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setString( ResourceID, Str ); +} +void StringResourceWithStorageImpl::setStringForLocale + ( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setStringForLocale( ResourceID, Str, locale ); +} +void StringResourceWithStorageImpl::removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeId( ResourceID ); +} +void StringResourceWithStorageImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeIdForLocale( ResourceID, locale ); +} +void StringResourceWithStorageImpl::newLocale( const Locale& locale ) + throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::newLocale( locale ); +} +void StringResourceWithStorageImpl::removeLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeLocale( locale ); +} +sal_Int32 StringResourceWithStorageImpl::getUniqueNumericId( ) + throw (RuntimeException, NoSupportException) +{ + return StringResourceImpl::getUniqueNumericId(); +} + +// XStringResourcePersistence +void StringResourceWithStorageImpl::store() + throw (NoSupportException, Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceWithStorageImpl::store(): Read only" ); + + bool bUsedForStore = true; + bool bStoreAll = m_bStorageChanged; + m_bStorageChanged = false; + if( !m_bModified && !bStoreAll ) + return; + + implStoreAtStorage( m_aNameBase, m_aComment, m_xStorage, bUsedForStore, bStoreAll ); + m_bModified = false; +} + +sal_Bool StringResourceWithStorageImpl::isModified( ) + throw (RuntimeException) +{ + return StringResourcePersistenceImpl::isModified(); +} +void StringResourceWithStorageImpl::setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException) +{ + StringResourcePersistenceImpl::setComment( Comment ); +} +void StringResourceWithStorageImpl::storeToStorage( const Reference< XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (Exception, RuntimeException) +{ + StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment ); +} +void StringResourceWithStorageImpl::storeToURL( const ::rtl::OUString& URL, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment, + const Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (Exception, RuntimeException) +{ + StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler ); +} +Sequence< ::sal_Int8 > StringResourceWithStorageImpl::exportBinary( ) + throw (RuntimeException) +{ + return StringResourcePersistenceImpl::exportBinary(); +} +void StringResourceWithStorageImpl::importBinary( const Sequence< ::sal_Int8 >& Data ) + throw (IllegalArgumentException, RuntimeException) +{ + StringResourcePersistenceImpl::importBinary( Data ); +} + +// ----------------------------------------------------------------------------- +// XStringResourceWithStorage + +void StringResourceWithStorageImpl::storeAsStorage( const Reference< XStorage >& Storage ) + throw (Exception, RuntimeException) +{ + setStorage( Storage ); + store(); +} + +void StringResourceWithStorageImpl::setStorage( const Reference< XStorage >& Storage ) + throw (IllegalArgumentException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + if( !Storage.is() ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii + ( "StringResourceWithStorageImpl::setStorage: invalid storage" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } + + implLoadAllLocales(); + + m_xStorage = Storage; + m_bStorageChanged = true; +} + + +// ============================================================================= +// Private helper methods +// ============================================================================= + +// Scan locale properties files +void StringResourceWithStorageImpl::implScanLocales( void ) +{ + Reference< container::XNameAccess > xNameAccess( m_xStorage, UNO_QUERY ); + if( xNameAccess.is() ) + { + Sequence< ::rtl::OUString > aContentSeq = xNameAccess->getElementNames(); + implScanLocaleNames( aContentSeq ); + } + + implLoadAllLocales(); +} + +// Loading +bool StringResourceWithStorageImpl::implLoadLocale( LocaleItem* pLocaleItem ) +{ + bool bSuccess = false; + try + { + ::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase ); + aStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".properties") ); + + Reference< io::XStream > xElementStream = + m_xStorage->openStreamElement( aStreamName, ElementModes::READ ); + + if( xElementStream.is() ) + { + Reference< io::XInputStream > xInputStream = xElementStream->getInputStream(); + if( xInputStream.is() ) + { + bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream ); + xInputStream->closeInput(); + } + } + } + catch( uno::Exception& ) + {} + + return bSuccess; +} + + +// ============================================================================= +// StringResourceWithLocationImpl +// ============================================================================= + +// component operations +static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceWithLocationImpl() +{ + Sequence< ::rtl::OUString > names(1); + names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithLocation") ); + return names; +} + +static ::rtl::OUString getImplementationName_StringResourceWithLocationImpl() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResourceWithLocation") ); +} + +static Reference< XInterface > SAL_CALL create_StringResourceWithLocationImpl( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) +{ + return static_cast< ::cppu::OWeakObject * >( new StringResourceWithLocationImpl( xContext ) ); +} + +// ----------------------------------------------------------------------------- + +StringResourceWithLocationImpl::StringResourceWithLocationImpl( const Reference< XComponentContext >& rxContext ) + : StringResourceWithLocationImpl_BASE( rxContext ) + , m_bLocationChanged( false ) +{ +} + +// ----------------------------------------------------------------------------- + +StringResourceWithLocationImpl::~StringResourceWithLocationImpl() +{ +} + +// ----------------------------------------------------------------------------- +// XServiceInfo +// ----------------------------------------------------------------------------- + +::rtl::OUString StringResourceWithLocationImpl::getImplementationName( ) throw (RuntimeException) +{ + return getImplementationName_StringResourceWithLocationImpl(); +} + +// ----------------------------------------------------------------------------- + +sal_Bool StringResourceWithLocationImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); + const ::rtl::OUString* pNames = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pNames + aNames.getLength(); + for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) + ; + + return pNames != pEnd; +} + +// ----------------------------------------------------------------------------- + +Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getSupportedServiceNames( ) throw (RuntimeException) +{ + return getSupportedServiceNames_StringResourceWithLocationImpl(); +} + +// ----------------------------------------------------------------------------- +// XInitialization +// ----------------------------------------------------------------------------- + +void StringResourceWithLocationImpl::initialize( const Sequence< Any >& aArguments ) + throw (Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + if ( aArguments.getLength() != 6 ) + { + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM + ( "XInitialization::initialize: invalid number of arguments!" ) ), + Reference< XInterface >() ); + } + + bool bOk = (aArguments[0] >>= m_aLocation); + sal_Int32 nLen = m_aLocation.getLength(); + if( bOk && nLen == 0 ) + { + bOk = false; + } + else + { + if( m_aLocation.getStr()[nLen - 1] != '/' ) + m_aLocation += ::rtl::OUString::createFromAscii( "/" ); + } + + if( !bOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: invalid URL" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } + + + bOk = (aArguments[5] >>= m_xInteractionHandler); + if( !bOk ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceWithStorageImpl::initialize: invalid type" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 5 ); + } + + implInitializeCommonParameters( aArguments ); +} + +// ----------------------------------------------------------------------------- +// Forwarding calls to base class + +// XModifyBroadcaster +void StringResourceWithLocationImpl::addModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::addModifyListener( aListener ); +} +void StringResourceWithLocationImpl::removeModifyListener( const Reference< XModifyListener >& aListener ) + throw (RuntimeException) +{ + StringResourceImpl::removeModifyListener( aListener ); +} + +// XStringResourceResolver +::rtl::OUString StringResourceWithLocationImpl::resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveString( ResourceID ) ; +} +::rtl::OUString StringResourceWithLocationImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException) +{ + return StringResourceImpl::resolveStringForLocale( ResourceID, locale ); +} +sal_Bool StringResourceWithLocationImpl::hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForId( ResourceID ) ; +} +sal_Bool StringResourceWithLocationImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const Locale& locale ) + throw (RuntimeException) +{ + return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale ); +} +Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getResourceIDs( ) + throw (RuntimeException) +{ + return StringResourceImpl::getResourceIDs(); +} +Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getResourceIDsForLocale + ( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException) +{ + return StringResourceImpl::getResourceIDsForLocale( locale ); +} +Locale StringResourceWithLocationImpl::getCurrentLocale() + throw (RuntimeException) +{ + return StringResourceImpl::getCurrentLocale(); +} +Locale StringResourceWithLocationImpl::getDefaultLocale( ) + throw (RuntimeException) +{ + return StringResourceImpl::getDefaultLocale(); +} +Sequence< Locale > StringResourceWithLocationImpl::getLocales( ) + throw (RuntimeException) +{ + return StringResourceImpl::getLocales(); +} + +// XStringResourceManager +sal_Bool StringResourceWithLocationImpl::isReadOnly() + throw (RuntimeException) +{ + return StringResourceImpl::isReadOnly(); +} +void StringResourceWithLocationImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch ) + throw (IllegalArgumentException, RuntimeException) +{ + StringResourceImpl::setCurrentLocale( locale, FindClosestMatch ); +} +void StringResourceWithLocationImpl::setDefaultLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException,NoSupportException) +{ + StringResourceImpl::setDefaultLocale( locale ); +} +void StringResourceWithLocationImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setString( ResourceID, Str ); +} +void StringResourceWithLocationImpl::setStringForLocale + ( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale ) + throw (NoSupportException, RuntimeException) +{ + StringResourceImpl::setStringForLocale( ResourceID, Str, locale ); +} +void StringResourceWithLocationImpl::removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeId( ResourceID ); +} +void StringResourceWithLocationImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeIdForLocale( ResourceID, locale ); +} +void StringResourceWithLocationImpl::newLocale( const Locale& locale ) + throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::newLocale( locale ); +} +void StringResourceWithLocationImpl::removeLocale( const Locale& locale ) + throw (IllegalArgumentException, RuntimeException, NoSupportException) +{ + StringResourceImpl::removeLocale( locale ); +} +sal_Int32 StringResourceWithLocationImpl::getUniqueNumericId( ) + throw (RuntimeException, NoSupportException) +{ + return StringResourceImpl::getUniqueNumericId(); +} + +// XStringResourcePersistence +void StringResourceWithLocationImpl::store() + throw (NoSupportException, Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceWithLocationImpl::store(): Read only" ); + + bool bUsedForStore = true; + bool bStoreAll = m_bLocationChanged; + m_bLocationChanged = false; + if( !m_bModified && !bStoreAll ) + return; + + Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess(); + implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment, + xFileAccess, bUsedForStore, bStoreAll ); + m_bModified = false; +} + +sal_Bool StringResourceWithLocationImpl::isModified( ) + throw (RuntimeException) +{ + return StringResourcePersistenceImpl::isModified(); +} +void StringResourceWithLocationImpl::setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException) +{ + StringResourcePersistenceImpl::setComment( Comment ); +} +void StringResourceWithLocationImpl::storeToStorage( const Reference< XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (Exception, RuntimeException) +{ + StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment ); +} +void StringResourceWithLocationImpl::storeToURL( const ::rtl::OUString& URL, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment, + const Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (Exception, RuntimeException) +{ + StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler ); +} +Sequence< ::sal_Int8 > StringResourceWithLocationImpl::exportBinary( ) + throw (RuntimeException) +{ + return StringResourcePersistenceImpl::exportBinary(); +} +void StringResourceWithLocationImpl::importBinary( const Sequence< ::sal_Int8 >& Data ) + throw (IllegalArgumentException, RuntimeException) +{ + StringResourcePersistenceImpl::importBinary( Data ); +} + +// ----------------------------------------------------------------------------- +// XStringResourceWithLocation + +// XStringResourceWithLocation +void StringResourceWithLocationImpl::storeAsURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + setURL( URL ); + store(); +} + +void StringResourceWithLocationImpl::setURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + implCheckReadOnly( "StringResourceWithLocationImpl::setURL(): Read only" ); + + sal_Int32 nLen = URL.getLength(); + if( nLen == 0 ) + { + ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii + ( "StringResourceWithLocationImpl::setURL: invalid URL" ); + throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 ); + } + + implLoadAllLocales(); + + // Delete files at old location + bool bUsedForStore = false; + bool bStoreAll = false; + bool bKillAll = true; + implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment, + getFileAccess(), bUsedForStore, bStoreAll, bKillAll ); + + m_aLocation = URL; + m_bLocationChanged = true; +} + + +// ============================================================================= +// Private helper methods +// ============================================================================= + +// Scan locale properties files +void StringResourceWithLocationImpl::implScanLocales( void ) +{ + const Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess(); + if( xFileAccess.is() && xFileAccess->isFolder( m_aLocation ) ) + { + Sequence< ::rtl::OUString > aContentSeq = xFileAccess->getFolderContents( m_aLocation, false ); + implScanLocaleNames( aContentSeq ); + } +} + +// Loading +bool StringResourceWithLocationImpl::implLoadLocale( LocaleItem* pLocaleItem ) +{ + bool bSuccess = false; + + const Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess(); + if( xFileAccess.is() ) + { + ::rtl::OUString aCompleteFileName = + implGetPathForLocaleItem( pLocaleItem, m_aNameBase, m_aLocation ); + + Reference< io::XInputStream > xInputStream; + try + { + xInputStream = xFileAccess->openFileRead( aCompleteFileName ); + } + catch( Exception& ) + {} + if( xInputStream.is() ) + { + bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream ); + xInputStream->closeInput(); + } + } + + return bSuccess; +} + +const Reference< ucb::XSimpleFileAccess > StringResourceWithLocationImpl::getFileAccess( void ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + if( !m_xSFI.is() ) + { + Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory(); + m_xSFI = Reference< ucb::XSimpleFileAccess >( xMCF->createInstanceWithContext + ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ), UNO_QUERY ); + + if( m_xSFI.is() && m_xInteractionHandler.is() ) + m_xSFI->setInteractionHandler( m_xInteractionHandler ); + } + return m_xSFI; +} + + +// ============================================================================= +// component export operations +// ============================================================================= + +static struct ::cppu::ImplementationEntry s_component_entries [] = +{ + { + create_StringResourceImpl, getImplementationName_StringResourceImpl, + getSupportedServiceNames_StringResourceImpl, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { + create_StringResourceWithLocationImpl, getImplementationName_StringResourceWithLocationImpl, + getSupportedServiceNames_StringResourceWithLocationImpl, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { + create_StringResourceWithStorageImpl, getImplementationName_StringResourceWithStorageImpl, + getSupportedServiceNames_StringResourceWithStorageImpl, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } +}; + + +//......................................................................... +} // namespace dlgprov +//......................................................................... + + +// ============================================================================= +// component exports +// ============================================================================= + +extern "C" +{ + void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) + { + (void)ppEnv; + + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_writeInfoHelper( + pServiceManager, pRegistryKey, ::stringresource::s_component_entries ); + } + + void * SAL_CALL component_getFactory( + const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + return ::cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, ::stringresource::s_component_entries ); + } +} diff --git a/scripting/source/stringresource/stringresource.hxx b/scripting/source/stringresource/stringresource.hxx new file mode 100644 index 000000000000..c69c614db7cb --- /dev/null +++ b/scripting/source/stringresource/stringresource.hxx @@ -0,0 +1,691 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SCRIPTING_DLGPROV_HXX +#define SCRIPTING_DLGPROV_HXX + +#ifndef _COM_SUN_STAR_AWT_XSTRINGRESOURCEWITHSTORAGE_HPP_ +#include <com/sun/star/resource/XStringResourceWithStorage.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_XSTRINGRESOURCEWITHSTORAGE_HPP_ +#include <com/sun/star/resource/XStringResourceWithLocation.hpp> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <osl/mutex.hxx> + +#include <vector> +#include <hash_map> + +//......................................................................... +namespace stringresource +{ +//......................................................................... + +// ============================================================================= +// mutex +// ============================================================================= + +::osl::Mutex& getMutex(); + + +// ============================================================================= +// class stringresourceImpl +// ============================================================================= + +// Hashtable to map string ids to string +struct hashName_Impl +{ + size_t operator()(const ::rtl::OUString Str) const + { + return (size_t)Str.hashCode(); + } +}; + +struct eqName_Impl +{ + sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const + { + return ( Str1 == Str2 ); + } +}; + +typedef std::hash_map +< + ::rtl::OUString, + ::rtl::OUString, + hashName_Impl, + eqName_Impl +> +IdToStringMap; + +typedef std::hash_map +< + ::rtl::OUString, + sal_Int32, + hashName_Impl, + eqName_Impl +> +IdToIndexMap; + + +struct LocaleItem +{ + ::com::sun::star::lang::Locale m_locale; + IdToStringMap m_aIdToStringMap; + IdToIndexMap m_aIdToIndexMap; + sal_Int32 m_nNextIndex; + bool m_bLoaded; + bool m_bModified; + + LocaleItem( ::com::sun::star::lang::Locale locale, bool bLoaded=true ) + : m_locale( locale ) + , m_nNextIndex( 0 ) + , m_bLoaded( bLoaded ) + , m_bModified( false ) + {} +}; + +typedef std::vector< LocaleItem* > LocaleItemVector; +typedef std::vector< LocaleItem* >::iterator LocaleItemVectorIt; +typedef std::vector< LocaleItem* >::const_iterator LocaleItemVectorConstIt; + +typedef ::cppu::WeakImplHelper2< + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::resource::XStringResourceManager > StringResourceImpl_BASE; + +class StringResourceImpl : public StringResourceImpl_BASE +{ +protected: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiComponentFactory > m_xMCF; + + LocaleItem* m_pCurrentLocaleItem; + LocaleItem* m_pDefaultLocaleItem; + bool m_bDefaultModified; + + ::cppu::OInterfaceContainerHelper m_aListenerContainer; + + LocaleItemVector m_aLocaleItemVector; + LocaleItemVector m_aDeletedLocaleItemVector; + LocaleItemVector m_aChangedDefaultLocaleVector; + + bool m_bModified; + bool m_bReadOnly; + + sal_Int32 m_nNextUniqueNumericId; + + // Scans ResourceID to start with number and adapt m_nNextUniqueNumericId + void implScanIdForNumber( const ::rtl::OUString& ResourceID ); + const static sal_Int32 UNIQUE_NUMBER_NEEDS_INITIALISATION = -1; + + // Checks read only status and throws exception if it's true + void implCheckReadOnly( const sal_Char* pExceptionMsg ) + throw (::com::sun::star::lang::NoSupportException); + + // Return the context's MultiComponentFactory + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiComponentFactory > + getMultiComponentFactory( void ); + + // Returns the LocalItem for a given locale, if it exists, otherwise NULL + // This method compares the locales exactly, no closest match search is performed + LocaleItem* getItemForLocale( const ::com::sun::star::lang::Locale& locale, sal_Bool bException ) + throw (::com::sun::star::lang::IllegalArgumentException); + + // Returns the LocalItem for a given locale, if it exists, otherwise NULL + // This method performes a closest match search, at least the language must match + LocaleItem* getClosestMatchItemForLocale( const ::com::sun::star::lang::Locale& locale ); + void implSetCurrentLocale( const ::com::sun::star::lang::Locale& locale, + sal_Bool FindClosestMatch, sal_Bool bUseDefaultIfNoMatch ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + void implModified( void ); + void implNotifyListeners( void ); + + //=== Impl methods for ...ForLocale methods === + ::rtl::OUString SAL_CALL implResolveString( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ) + throw (::com::sun::star::resource::MissingResourceException); + ::sal_Bool implHasEntryForId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ); + ::com::sun::star::uno::Sequence< ::rtl::OUString > implGetResourceIDs( LocaleItem* pLocaleItem ); + void implSetString( const ::rtl::OUString& ResourceID, + const ::rtl::OUString& Str, LocaleItem* pLocaleItem ); + void implRemoveId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem ) + throw (::com::sun::star::resource::MissingResourceException); + + // Method to load a locale if necessary, returns true if loading was + // successful. Default implementation in base class just returns true. + virtual bool loadLocale( LocaleItem* pLocaleItem ); + + virtual void implLoadAllLocales( void ); + +public: + StringResourceImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~StringResourceImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceResolver + virtual ::rtl::OUString SAL_CALL resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL resolveStringForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDs( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDsForLocale + ( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getCurrentLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getDefaultLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getLocales( ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceManager + virtual ::sal_Bool SAL_CALL isReadOnly() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCurrentLocale( const ::com::sun::star::lang::Locale& locale, ::sal_Bool FindClosestMatch ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStringForLocale( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL removeIdForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL newLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual ::sal_Int32 SAL_CALL getUniqueNumericId( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::RuntimeException); + }; + +typedef ::cppu::ImplInheritanceHelper1< + StringResourceImpl, + ::com::sun::star::resource::XStringResourcePersistence > StringResourcePersistenceImpl_BASE; + +class BinaryOutput; +class BinaryInput; + +class StringResourcePersistenceImpl : public StringResourcePersistenceImpl_BASE +{ +protected: + ::rtl::OUString m_aNameBase; + ::rtl::OUString m_aComment; + + void SAL_CALL implInitializeCommonParameters + ( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // Scan locale properties files + virtual void implScanLocales( void ); + + // Method to load a locale if necessary, returns true if loading was successful + virtual bool loadLocale( LocaleItem* pLocaleItem ); + + // does the actual loading + virtual bool implLoadLocale( LocaleItem* pLocaleItem ); + + virtual void implLoadAllLocales( void ); + + void implScanLocaleNames( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aContentSeq ); + ::rtl::OUString implGetFileNameForLocaleItem( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase ); + ::rtl::OUString implGetPathForLocaleItem( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aLocation, bool bDefaultFile=false ); + + bool implReadPropertiesFile( LocaleItem* pLocaleItem, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xInput ); + + bool implWritePropertiesFile( LocaleItem* pLocaleItem, const ::com::sun::star::uno::Reference + < ::com::sun::star::io::XOutputStream >& xOutputStream, const ::rtl::OUString& aComment ); + + void implWriteLocaleBinary( LocaleItem* pLocaleItem, BinaryOutput& rOut ); + + void implStoreAtStorage + ( + const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aComment, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage, + bool bUsedForStore, + bool bStoreAll + ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + void implKillRemovedLocaleFiles + ( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess + ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + void implKillChangedDefaultFiles + ( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess + ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + void implStoreAtLocation + ( + const ::rtl::OUString& Location, + const ::rtl::OUString& aNameBase, + const ::rtl::OUString& aComment, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess, + bool bUsedForStore, + bool bStoreAll, + bool bKillAll = false + ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + +public: + StringResourcePersistenceImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~StringResourcePersistenceImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceResolver + virtual ::rtl::OUString SAL_CALL resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL resolveStringForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDs( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDsForLocale + ( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getCurrentLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getDefaultLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getLocales( ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceManager + virtual ::sal_Bool SAL_CALL isReadOnly() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCurrentLocale( const ::com::sun::star::lang::Locale& locale, ::sal_Bool FindClosestMatch ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStringForLocale( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL removeIdForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL newLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual ::sal_Int32 SAL_CALL getUniqueNumericId( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::RuntimeException); + + // XStringResourcePersistence + virtual void SAL_CALL store( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::Exception, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isModified( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToStorage + ( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToURL( const ::rtl::OUString& URL, const ::rtl::OUString& NameBase, + const ::rtl::OUString& Comment, const ::com::sun::star::uno::Reference + < ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL exportBinary( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL importBinary( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Data ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); +}; + + +typedef ::cppu::ImplInheritanceHelper2< + StringResourcePersistenceImpl, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::resource::XStringResourceWithStorage > StringResourceWithStorageImpl_BASE; + +class StringResourceWithStorageImpl : public StringResourceWithStorageImpl_BASE +{ + ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > m_xStorage; + bool m_bStorageChanged; + + virtual void implScanLocales( void ); + virtual bool implLoadLocale( LocaleItem* pLocaleItem ); + +public: + StringResourceWithStorageImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~StringResourceWithStorageImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceResolver + virtual ::rtl::OUString SAL_CALL resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL resolveStringForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDs( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDsForLocale + ( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getCurrentLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getDefaultLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getLocales( ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceManager + virtual ::sal_Bool SAL_CALL isReadOnly() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCurrentLocale( const ::com::sun::star::lang::Locale& locale, ::sal_Bool FindClosestMatch ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStringForLocale( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL removeIdForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL newLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual ::sal_Int32 SAL_CALL getUniqueNumericId( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::RuntimeException); + + // XStringResourcePersistence + virtual void SAL_CALL store( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::Exception, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isModified( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToStorage + ( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToURL( const ::rtl::OUString& URL, const ::rtl::OUString& NameBase, + const ::rtl::OUString& Comment, const ::com::sun::star::uno::Reference + < ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL exportBinary( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL importBinary( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Data ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XStringResourceWithStorage + virtual void SAL_CALL storeAsStorage + ( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStorage + ( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); +}; + + +typedef ::cppu::ImplInheritanceHelper2< + StringResourcePersistenceImpl, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::resource::XStringResourceWithLocation > StringResourceWithLocationImpl_BASE; + +class StringResourceWithLocationImpl : public StringResourceWithLocationImpl_BASE +{ + ::rtl::OUString m_aLocation; + bool m_bLocationChanged; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFI; + com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInteractionHandler; + + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > getFileAccess( void ); + + virtual void implScanLocales( void ); + virtual bool implLoadLocale( LocaleItem* pLocaleItem ); + +public: + StringResourceWithLocationImpl( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + virtual ~StringResourceWithLocationImpl(); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceResolver + virtual ::rtl::OUString SAL_CALL resolveString( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL resolveStringForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw ( ::com::sun::star::resource::MissingResourceException, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDs( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getResourceIDsForLocale + ( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getCurrentLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getDefaultLocale( ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > SAL_CALL getLocales( ) + throw (::com::sun::star::uno::RuntimeException); + + // XStringResourceManager + virtual ::sal_Bool SAL_CALL isReadOnly() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setCurrentLocale( const ::com::sun::star::lang::Locale& locale, ::sal_Bool FindClosestMatch ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setStringForLocale( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeId( const ::rtl::OUString& ResourceID ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL removeIdForLocale( const ::rtl::OUString& ResourceID, + const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::resource::MissingResourceException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual void SAL_CALL newLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeLocale( const ::com::sun::star::lang::Locale& locale ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, + ::com::sun::star::lang::NoSupportException); + virtual ::sal_Int32 SAL_CALL getUniqueNumericId( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::RuntimeException); + + // XStringResourcePersistence + virtual void SAL_CALL store( ) + throw (::com::sun::star::lang::NoSupportException, + ::com::sun::star::uno::Exception, + ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isModified( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setComment( const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToStorage + ( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage, + const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL storeToURL( const ::rtl::OUString& URL, const ::rtl::OUString& NameBase, + const ::rtl::OUString& Comment, const ::com::sun::star::uno::Reference + < ::com::sun::star::task::XInteractionHandler >& Handler ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL exportBinary( ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL importBinary( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& Data ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + // XStringResourceWithLocation + virtual void SAL_CALL storeAsURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setURL( const ::rtl::OUString& URL ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); +}; + +//......................................................................... +} // namespace stringtable +//......................................................................... + +#endif // SCRIPTING_DLGPROV_HXX diff --git a/scripting/source/stringresource/stringresource.xml b/scripting/source/stringresource/stringresource.xml new file mode 100644 index 000000000000..51cbf9921d8a --- /dev/null +++ b/scripting/source/stringresource/stringresource.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name>stringresource</module-name> + + <component-description> + <author>Andreas Bregas</author> + <name>com.sun.star.comp.scripting.StringResource</name> + <description>string resource</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="drafts"/> + <supported-service>com.sun.star.resource.StringResource</supported-service> + <supported-service>com.sun.star.resource.StringResourceWithLocation</supported-service> + <supported-service>com.sun.star.resource.StringResourceWithStorage</supported-service> + <type>com.sun.star.resource.XStringResourceWithStorage</type> + <type>com.sun.star.lang.IllegalArgumentException</type> + <type>com.sun.star.lang.XInitialization</type> + <type>com.sun.star.lang.XMultiComponentFactory</type> + <type>com.sun.star.lang.XServiceInfo</type> + <type>com.sun.star.uno.XComponentContext</type> + <type>com.sun.star.ucb.XSimpleFileAccess3</type> + <type>com.sun.star.io.XInputStream</type> + </component-description> + + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> + <runtime-module-dependency>ucb</runtime-module-dependency> + +</module-description> diff --git a/scripting/source/vbaevents/eventhelper.cxx b/scripting/source/vbaevents/eventhelper.cxx new file mode 100644 index 000000000000..838d89d49c89 --- /dev/null +++ b/scripting/source/vbaevents/eventhelper.cxx @@ -0,0 +1,1045 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: eventhelper.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include <comphelper/processfactory.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/proparrhlp.hxx> +#include <comphelper/propertycontainer.hxx> + +#include <ooo/vba/XVBAToOOEventDescGen.hpp> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/lang/XServiceName.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <com/sun/star/frame/XModel.hpp> + +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp> + +#include <com/sun/star/drawing/XControlShape.hpp> + +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XDialog.hpp> +#include <com/sun/star/awt/KeyEvent.hpp> +#include <com/sun/star/awt/MouseEvent.hpp> +#include <com/sun/star/awt/XFixedText.hpp> //liuchen 2009-6-5 +#include <com/sun/star/awt/XTextComponent.hpp> //liuchen 2009-6-5 +#include <com/sun/star/awt/XComboBox.hpp> //liuchen 2009-6-18 +#include <com/sun/star/awt/XRadioButton.hpp> //liuchen 2009-7-30 + +#include <msforms/ReturnInteger.hpp> + +#include <sfx2/objsh.hxx> +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> +#include <basic/sbmeth.hxx> +#include <basic/sbmod.hxx> +#include <basic/sbx.hxx> + + + + +// for debug +#include <comphelper/anytostring.hxx> + + +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/script/XScriptListener.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <comphelper/evtmethodhelper.hxx> + +#include <set> +#include <list> +#include <hash_map> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::script; +using namespace ::com::sun::star::uno; +using namespace ::ooo::vba; + +#define MAP_CHAR_LEN(x) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x))//liuchen 2009-6-8 +#define GET_TYPE(x) ::getCppuType((uno::Reference< x > *)0); + +// Some constants +const static rtl::OUString DELIM = rtl::OUString::createFromAscii( "::" ); +const static sal_Int32 DELIMLEN = DELIM.getLength(); + +#if 0 +void dumpListeners( const Reference< beans::XIntrospection >& xIntrospection, const Reference<XInterface>& xIfc) +{ + Reference< beans::XIntrospectionAccess > xIntrospectionAccess; + if ( xIntrospection.is() ) + { + xIntrospectionAccess = xIntrospection->inspect( + makeAny( xIfc ) ); + Sequence< Type > aControlListeners = + xIntrospectionAccess->getSupportedListeners(); + sal_Int32 nLength = aControlListeners.getLength(); + + for ( sal_Int32 i = 0; i< nLength; ++i ) + { + Type& listType = aControlListeners[ i ]; + rtl::OUString sFullTypeName = listType.getTypeName(); + rtl::OUString sTypeName = listType.getTypeName(); + sal_Int32 lastDotIndex = -1; + if ( ( lastDotIndex = sFullTypeName.lastIndexOf( '.' ) ) > -1 ) + { + sTypeName = sFullTypeName.copy( lastDotIndex + 1 ); + } + Sequence< ::rtl::OUString > sMeths = comphelper::getEventMethodsForType( listType ); + sal_Int32 sMethLen = sMeths.getLength(); + for ( sal_Int32 j=0 ; j < sMethLen; ++j ) + { + OSL_TRACE("**Listener [%d] Type[%s] Method[%s]",j, + rtl::OUStringToOString( sTypeName, + RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( sMeths[ j ], + RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + } +} + +void dumpEvent( const ScriptEvent& evt ) +{ + OSL_TRACE("dumpEvent: Source %s", + rtl::OUStringToOString( comphelper::anyToString( makeAny(evt.Source)), + RTL_TEXTENCODING_UTF8 ).getStr() ); + + OSL_TRACE("dumpEvent: ScriptType %s", + rtl::OUStringToOString( evt.ScriptType, + RTL_TEXTENCODING_UTF8 ).getStr() ); + + OSL_TRACE("dumpEvent: ScriptCode %s", + rtl::OUStringToOString( evt.ScriptCode, + RTL_TEXTENCODING_UTF8 ).getStr() ); + + OSL_TRACE("dumpEvent: ListenerType %s", + rtl::OUStringToOString( evt.ListenerType.getTypeName(), + RTL_TEXTENCODING_UTF8 ).getStr() ); + + OSL_TRACE("dumpEvent: Listener methodname %s", + rtl::OUStringToOString( evt.MethodName, + RTL_TEXTENCODING_UTF8 ).getStr() ); + + OSL_TRACE("dumpEvent: arguments;"); + sal_Int32 nLen = evt.Arguments.getLength(); + for ( sal_Int32 index=0; index < nLen; ++index ) + { + OSL_TRACE("\t [%d] %s", index, + rtl::OUStringToOString( comphelper::anyToString( evt.Arguments[ index ] ), + RTL_TEXTENCODING_UTF8 ).getStr() ); + + } +} + +#endif + +bool isKeyEventOk( awt::KeyEvent& evt, const Sequence< Any >& params ) +{ + if ( !( params.getLength() > 0 ) || + !( params[ 0 ] >>= evt ) ) + return false; + return true; +} + +bool isMouseEventOk( awt::MouseEvent& evt, const Sequence< Any >& params ) +{ + if ( !( params.getLength() > 0 ) || + !( params[ 0 ] >>= evt ) ) + return false; + return true; +} + +Sequence< Any > ooMouseEvtToVBADblClick( const Sequence< Any >& params ) +{ + Sequence< Any > translatedParams; + awt::MouseEvent evt; + + if ( !( isMouseEventOk(evt, params)) || + (evt.ClickCount != 2) ) + return Sequence< Any >(); + // give back orig params, this will signal that the event is good + return params; +} + +Sequence< Any > ooMouseEvtToVBAMouseEvt( const Sequence< Any >& params ) +{ + Sequence< Any > translatedParams; + awt::MouseEvent evt; + + if ( !isMouseEventOk(evt, params) ) + return Sequence< Any >(); + + translatedParams.realloc(4); + + // Buttons + translatedParams[ 0 ] <<= evt.Buttons; + // Shift + translatedParams[ 1 ] <<= evt.Modifiers; + // X + translatedParams[ 2 ] <<= evt.X; + // Y + translatedParams[ 3 ] <<= evt.Y; + return translatedParams; +} + +Sequence< Any > ooKeyPressedToVBAKeyPressed( const Sequence< Any >& params ) +{ + Sequence< Any > translatedParams; + awt::KeyEvent evt; + + if ( !isKeyEventOk( evt, params ) ) + return Sequence< Any >(); + + translatedParams.realloc(1); + + msforms::ReturnInteger keyCode; + keyCode.Value = evt.KeyCode; + translatedParams[0] <<= keyCode; + return translatedParams; +} + +Sequence< Any > ooKeyPressedToVBAKeyUpDown( const Sequence< Any >& params ) +{ + Sequence< Any > translatedParams; + awt::KeyEvent evt; + + if ( !isKeyEventOk( evt, params ) ) + return Sequence< Any >(); + + translatedParams.realloc(2); + + msforms::ReturnInteger keyCode; + sal_Int8 shift = sal::static_int_cast<sal_Int8>( evt.Modifiers ); + + // #TODO check whether values from OOO conform to values generated from vba + keyCode.Value = evt.KeyCode; + translatedParams[0] <<= keyCode; + translatedParams[1] <<= shift; + return translatedParams; +} + +typedef Sequence< Any > (*Translator)(const Sequence< Any >&); + +//liuchen 2009-6-23 +//expand the "TranslateInfo" struct to support more kinds of events +struct TranslateInfo +{ + rtl::OUString sVBAName; //vba event name + Translator toVBA; //the method to convert OO event parameters to VBA event parameters + bool (*ApproveRule)(const ScriptEvent& evt, void* pPara); //this method is used to determine which types of controls should execute the event + void *pPara; //Parameters for the above approve method +}; + + +typedef std::hash_map< rtl::OUString, +std::list< TranslateInfo >, +::rtl::OUStringHash, +::std::equal_to< ::rtl::OUString > > EventInfoHash; + +//liuchen 2009-6-23 +struct TranslatePropMap +{ + rtl::OUString sEventInfo; //OO event name + TranslateInfo aTransInfo; +}; + +bool ApproveAll(const ScriptEvent& evt, void* pPara); //allow all types of controls to execute the event +bool ApproveType(const ScriptEvent& evt, void* pPara); //certain types of controls should execute the event, those types are given by pPara +bool DenyType(const ScriptEvent& evt, void* pPara); //certain types of controls should not execute the event, those types are given by pPara +bool DenyMouseDrag(const ScriptEvent& evt, void* pPara); //used for VBA MouseMove event when "Shift" key is pressed + +struct TypeList +{ + uno::Type* pTypeList; + int nListLength; +}; + +Type typeXFixedText = GET_TYPE(awt::XFixedText) +Type typeXTextComponent = GET_TYPE(awt::XTextComponent) +Type typeXComboBox = GET_TYPE(awt::XComboBox) +Type typeXRadioButton = GET_TYPE(awt::XRadioButton) + + +TypeList fixedTextList = {&typeXFixedText, 1}; +TypeList textCompList = {&typeXTextComponent, 1}; +TypeList radioButtonList = {&typeXRadioButton, 1}; +TypeList comboBoxList = {&typeXComboBox, 1}; + +//this array stores the OO event to VBA event translation info +static TranslatePropMap aTranslatePropMap_Impl[] = +{ + // actionPerformed ooo event + { MAP_CHAR_LEN("actionPerformed"), { MAP_CHAR_LEN("_Click"), NULL, ApproveAll, NULL } }, + { MAP_CHAR_LEN("actionPerformed"), { MAP_CHAR_LEN("_Change"), NULL, DenyType, (void*)(&radioButtonList) } }, //liuchen 2009-7-30, OptionalButton_Change event is not the same as OptionalButton_Click event + + // itemStateChanged ooo event + { MAP_CHAR_LEN("itemStateChanged"), { MAP_CHAR_LEN("_Click"), NULL, ApproveType, (void*)(&comboBoxList) } }, //liuchen, add to support VBA ComboBox_Click event + { MAP_CHAR_LEN("itemStateChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveType, (void*)(&radioButtonList) } }, //liuchen 2009-7-30, OptionalButton_Change event should be triggered when the button state is changed + + // changed ooo event + { MAP_CHAR_LEN("changed"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } }, + + // focusGained ooo event + { MAP_CHAR_LEN("focusGained"), { MAP_CHAR_LEN("_GotFocus"), NULL, ApproveAll, NULL } }, + + // focusLost ooo event + { MAP_CHAR_LEN("focusLost"), { MAP_CHAR_LEN("_LostFocus"), NULL, ApproveAll, NULL } }, + { MAP_CHAR_LEN("focusLost"), { MAP_CHAR_LEN("_Exit"), NULL, ApproveType, (void*)(&textCompList) } }, //liuchen, add to support VBA TextBox_Exit event + + // adjustmentValueChanged ooo event + { MAP_CHAR_LEN("adjustmentValueChanged"), { MAP_CHAR_LEN("_Scroll"), NULL, ApproveAll, NULL } }, + { MAP_CHAR_LEN("adjustmentValueChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } }, + + // textChanged ooo event + { MAP_CHAR_LEN("textChanged"), { MAP_CHAR_LEN("_Change"), NULL, ApproveAll, NULL } }, + + // keyReleased ooo event + { MAP_CHAR_LEN("keyReleased"), { MAP_CHAR_LEN("_KeyUp"), ooKeyPressedToVBAKeyUpDown, ApproveAll, NULL } }, + + // mouseReleased ooo event + { MAP_CHAR_LEN("mouseReleased"), { MAP_CHAR_LEN("_Click"), ooMouseEvtToVBAMouseEvt, ApproveType, (void*)(&fixedTextList) } }, //liuchen, add to support VBA Label_Click event + { MAP_CHAR_LEN("mouseReleased"), { MAP_CHAR_LEN("_MouseUp"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } }, + + // mousePressed ooo event + { MAP_CHAR_LEN("mousePressed"), { MAP_CHAR_LEN("_MouseDown"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } }, + { MAP_CHAR_LEN("mousePressed"), { MAP_CHAR_LEN("_DblClick"), ooMouseEvtToVBADblClick, ApproveAll, NULL } }, + + // mouseMoved ooo event + { MAP_CHAR_LEN("mouseMoved"), { MAP_CHAR_LEN("_MouseMove"), ooMouseEvtToVBAMouseEvt, ApproveAll, NULL } }, + { MAP_CHAR_LEN("mouseDragged"), { MAP_CHAR_LEN("_MouseMove"), ooMouseEvtToVBAMouseEvt, DenyMouseDrag, NULL } }, //liuchen, add to support VBA MouseMove event when the "Shift" key is pressed + + // keyPressed ooo event + { MAP_CHAR_LEN("keyPressed"), { MAP_CHAR_LEN("_KeyDown"), ooKeyPressedToVBAKeyPressed, ApproveAll, NULL } }, + { MAP_CHAR_LEN("keyPressed"), { MAP_CHAR_LEN("_KeyPress"), ooKeyPressedToVBAKeyPressed, ApproveAll, NULL } } +}; + +EventInfoHash& getEventTransInfo() +{ + static bool initialised = false; + static EventInfoHash eventTransInfo; + if ( !initialised ) + { + rtl::OUString sEventInfo = MAP_CHAR_LEN(""); + TranslatePropMap* pTransProp = aTranslatePropMap_Impl; + int nCount = sizeof(aTranslatePropMap_Impl) / sizeof(aTranslatePropMap_Impl[0]); + + int i = 0; + while (i < nCount) + { + sEventInfo = pTransProp->sEventInfo; + std::list< TranslateInfo > infoList; + do + { + infoList.push_back( pTransProp->aTransInfo ); + pTransProp++; + i++; + }while(i < nCount && sEventInfo == pTransProp->sEventInfo); + eventTransInfo[sEventInfo] = infoList; + } + initialised = true; + } + return eventTransInfo; +} +//liuchen 2009-6-23 end + +// Helper class + +class ScriptEventHelper +{ +public: + ScriptEventHelper( const Reference< XInterface >& xControl ); + Sequence< ScriptEventDescriptor > createEvents( const rtl::OUString& sCodeName ); + Sequence< rtl::OUString > getEventListeners(); +private: + Reference< XComponentContext > m_xCtx; + Reference< XInterface > m_xControl; +}; + +bool +eventMethodToDescriptor( const ::rtl::OUString& rEventMethod, ScriptEventDescriptor& evtDesc, const ::rtl::OUString& sCodeName ) +{ + // format of ControlListener is TypeName::methodname e.g. + // "com.sun.star.awt.XActionListener::actionPerformed" or + // "XActionListener::actionPerformed + + ::rtl::OUString sMethodName; + ::rtl::OUString sTypeName; + sal_Int32 nDelimPos = rEventMethod.indexOf( DELIM ); + if ( nDelimPos == -1 ) + { + return false; + } + sMethodName = rEventMethod.copy( nDelimPos + DELIMLEN ); + sTypeName = rEventMethod.copy( 0, nDelimPos ); + + EventInfoHash& infos = getEventTransInfo(); + + // Only create an ScriptEventDescriptor for an event we can translate + // or emulate + if ( sMethodName.getLength() + && sTypeName.getLength() + && ( infos.find( sMethodName ) != infos.end() ) ) + { + // just fill in CodeName, when the event fires the other + // info is gathered from the event source to determine what + // event handler we try to call + evtDesc.ScriptCode = sCodeName; + evtDesc.ListenerType = sTypeName; + evtDesc.EventMethod = sMethodName; + + // set this it VBAInterop, ensures that it doesn't + // get persisted or shown in property editors + evtDesc.ScriptType = rtl::OUString::createFromAscii( + "VBAInterop" ); + return true; + } + return false; + +} + +ScriptEventHelper::ScriptEventHelper( const Reference< XInterface >& xControl ) : m_xControl( xControl ) +{ + Reference < beans::XPropertySet > xProps( + ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); + m_xCtx.set( xProps->getPropertyValue( rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), + uno::UNO_QUERY_THROW ); +} + +Sequence< rtl::OUString > +ScriptEventHelper::getEventListeners() +{ + Reference< lang::XMultiComponentFactory > xMFac( + m_xCtx->getServiceManager(), UNO_QUERY ); + std::list< rtl::OUString > eventMethods; + + if ( xMFac.is() ) + { + Reference< beans::XIntrospection > xIntrospection( + xMFac->createInstanceWithContext( rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ), m_xCtx ), UNO_QUERY ); +#if 0 + dumpListeners( xIntrospection, m_xControl ); + dumpListeners( xIntrospection, m_xControl->getModel() ); +#endif + Reference< beans::XIntrospectionAccess > xIntrospectionAccess; + if ( xIntrospection.is() ) + { + xIntrospectionAccess = xIntrospection->inspect( + makeAny( m_xControl ) ); + Sequence< Type > aControlListeners = + xIntrospectionAccess->getSupportedListeners(); + sal_Int32 nLength = aControlListeners.getLength(); + for ( sal_Int32 i = 0; i< nLength; ++i ) + { + Type& listType = aControlListeners[ i ]; + rtl::OUString sFullTypeName = listType.getTypeName(); + Sequence< ::rtl::OUString > sMeths = + comphelper::getEventMethodsForType( listType ); + sal_Int32 sMethLen = sMeths.getLength(); + for ( sal_Int32 j=0 ; j < sMethLen; ++j ) + { + rtl::OUString sEventMethod = sFullTypeName; + sEventMethod += DELIM; + sEventMethod += sMeths[ j ]; + eventMethods.push_back( sEventMethod ); + } + } + + } + } + + Sequence< rtl::OUString > sEventMethodNames( eventMethods.size() ); + std::list< rtl::OUString >::const_iterator it = eventMethods.begin(); + rtl::OUString* pDest = sEventMethodNames.getArray(); + + for ( ; it != eventMethods.end(); ++it, ++pDest ) + *pDest = *it; + + return sEventMethodNames; +} + +Sequence< ScriptEventDescriptor > +ScriptEventHelper::createEvents( const rtl::OUString& sCodeName ) +{ + Sequence< rtl::OUString > aControlListeners = getEventListeners(); + rtl::OUString* pSrc = aControlListeners.getArray(); + sal_Int32 nLength = aControlListeners.getLength(); + + Sequence< ScriptEventDescriptor > aDest( nLength ); + sal_Int32 nEvts = 0; + for ( sal_Int32 i = 0; i< nLength; ++i, ++pSrc ) + { + // from getListeners eventName is of form + // "com.sun.star.awt.XActionListener::actionPerformed" + // we need to strip "com.sun.star.awt." from that for form + // controls + ScriptEventDescriptor evtDesc; + if ( eventMethodToDescriptor( *pSrc, evtDesc, sCodeName ) ) + { + sal_Int32 dIndex = nEvts; + ++nEvts; + if ( nEvts > aDest.getLength() ) + aDest.realloc( nEvts );// should never happen + aDest[ dIndex ] = evtDesc; + } + } + aDest.realloc( nEvts ); + + return aDest; +} + + +typedef ::cppu::WeakImplHelper1< container::XNameContainer > NameContainer_BASE; + +class ReadOnlyEventsNameContainer : public NameContainer_BASE +{ +public: + ReadOnlyEventsNameContainer( const Sequence< rtl::OUString >& eventMethods, const rtl::OUString& sCodeName ); + // XNameContainer + + virtual void SAL_CALL insertByName( const ::rtl::OUString&, const Any& ) throw (lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, RuntimeException) + { + throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() ); + + } + virtual void SAL_CALL removeByName( const ::rtl::OUString& ) throw (::com::sun::star::container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) + { + throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() ); + } + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString&, const Any& ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, RuntimeException) + { + throw RuntimeException( rtl::OUString::createFromAscii( "ReadOnly container" ), Reference< XInterface >() ); + + } + + // XNameAccess + virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (RuntimeException); + + // XElementAccess + virtual Type SAL_CALL getElementType( ) throw (RuntimeException) + { return getCppuType(static_cast< const rtl::OUString * >(0) ); } + virtual ::sal_Bool SAL_CALL hasElements( ) throw (RuntimeException) + { return ( ( m_hEvents.size() > 0 ? sal_True : sal_False ) ); } +private: + +typedef std::hash_map< rtl::OUString, Any, ::rtl::OUStringHash, +::std::equal_to< ::rtl::OUString > > EventSupplierHash; + + EventSupplierHash m_hEvents; +}; + +ReadOnlyEventsNameContainer::ReadOnlyEventsNameContainer( const Sequence< rtl::OUString >& eventMethods, const rtl::OUString& sCodeName ) +{ + const rtl::OUString* pSrc = eventMethods.getConstArray(); + sal_Int32 nLen = eventMethods.getLength(); + for ( sal_Int32 index = 0; index < nLen; ++index, ++pSrc ) + { + Any aDesc; + ScriptEventDescriptor evtDesc; + if ( eventMethodToDescriptor( *pSrc, evtDesc, sCodeName ) ) + { + aDesc <<= evtDesc; + m_hEvents[ *pSrc ] = aDesc; + } + } +} + +Any SAL_CALL +ReadOnlyEventsNameContainer::getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException){ + EventSupplierHash::const_iterator it = m_hEvents.find( aName ); + if ( it == m_hEvents.end() ) + throw container::NoSuchElementException(); + return it->second; +} + +Sequence< ::rtl::OUString > SAL_CALL +ReadOnlyEventsNameContainer::getElementNames( ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > names(m_hEvents.size()); + rtl::OUString* pDest = names.getArray(); + EventSupplierHash::const_iterator it = m_hEvents.begin(); + EventSupplierHash::const_iterator it_end = m_hEvents.end(); + for ( sal_Int32 index = 0; it != it_end; ++index, ++pDest, ++it ) + *pDest = it->first; + return names; +} + +sal_Bool SAL_CALL +ReadOnlyEventsNameContainer::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException) +{ + EventSupplierHash::const_iterator it = m_hEvents.find( aName ); + if ( it == m_hEvents.end() ) + return sal_False; + return sal_True; +} + +typedef ::cppu::WeakImplHelper1< XScriptEventsSupplier > EventsSupplier_BASE; + +class ReadOnlyEventsSupplier : public EventsSupplier_BASE +{ +public: + ReadOnlyEventsSupplier( const Sequence< ::rtl::OUString >& eventMethods, const rtl::OUString& sCodeName ) + { m_xNameContainer = new ReadOnlyEventsNameContainer( eventMethods, sCodeName ); } + + // XScriptEventSupplier + virtual Reference< container::XNameContainer > SAL_CALL getEvents( ) throw (RuntimeException){ return m_xNameContainer; } +private: + Reference< container::XNameContainer > m_xNameContainer; +}; + +typedef ::cppu::WeakImplHelper2< XScriptListener, lang::XInitialization > EventListener_BASE; + +#define EVENTLSTNR_PROPERTY_ID_MODEL 1 +#define EVENTLSTNR_PROPERTY_MODEL ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Model" ) ) + +class EventListener : public EventListener_BASE + ,public ::comphelper::OMutexAndBroadcastHelper + ,public ::comphelper::OPropertyContainer + ,public ::comphelper::OPropertyArrayUsageHelper< EventListener > + +{ + +public: + EventListener( const Reference< XComponentContext >& rxContext ); + // XEventListener + virtual void SAL_CALL disposing(const lang::EventObject& Source) throw( RuntimeException ); + using cppu::OPropertySetHelper::disposing; + + // XScriptListener + virtual void SAL_CALL firing(const ScriptEvent& evt) throw(RuntimeException); + virtual Any SAL_CALL approveFiring(const ScriptEvent& evt) throw(reflection::InvocationTargetException, RuntimeException); + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw (::com::sun::star::uno::RuntimeException); + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException); + // XInterface + DECLARE_XINTERFACE() + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + virtual void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { + OPropertyContainer::setFastPropertyValue( nHandle, rValue ); + if ( nHandle == EVENTLSTNR_PROPERTY_ID_MODEL ) + setShellFromModel(); + } + +protected: + // OPropertySetHelper + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( ); + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; + +private: + void setShellFromModel(); + void firing_Impl( const ScriptEvent& evt, Any *pSyncRet=NULL ) throw( RuntimeException ); + + Reference< XComponentContext > m_xContext; + Reference< frame::XModel > m_xModel; + SfxObjectShell* mpShell; + +}; + +EventListener::EventListener( const Reference< XComponentContext >& rxContext ) : +OPropertyContainer(GetBroadcastHelper()), m_xContext( rxContext ), mpShell( 0 ) +{ + registerProperty( EVENTLSTNR_PROPERTY_MODEL, EVENTLSTNR_PROPERTY_ID_MODEL, + beans::PropertyAttribute::TRANSIENT, &m_xModel, ::getCppuType( &m_xModel ) ); + +} + +void +EventListener::setShellFromModel() +{ + // reset mpShell + mpShell = 0; + SfxObjectShell* pShell = SfxObjectShell::GetFirst(); + while ( m_xModel.is() && pShell ) + { + if ( pShell->GetModel() == m_xModel ) + { + mpShell = pShell; + break; + } + pShell = SfxObjectShell::GetNext( *pShell ); + } +} + +//XEventListener +void +EventListener::disposing(const lang::EventObject&) throw( RuntimeException ) +{ +} + +//XScriptListener + +void SAL_CALL +EventListener::firing(const ScriptEvent& evt) throw(RuntimeException) +{ + firing_Impl( evt ); +} + +Any SAL_CALL +EventListener::approveFiring(const ScriptEvent& evt) throw(reflection::InvocationTargetException, RuntimeException) +{ + Any ret; + firing_Impl( evt, &ret ); + return ret; +} + +// XInitialization +void SAL_CALL +EventListener::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) +{ + if ( aArguments.getLength() == 1 ) + aArguments[0] >>= m_xModel; + OSL_TRACE("EventListener::initialize() args %d m_xModel %d", aArguments.getLength(), m_xModel.is() ); +} + +// XInterface + +IMPLEMENT_FORWARD_XINTERFACE2( EventListener, EventListener_BASE, OPropertyContainer ) + +// XTypeProvider + +IMPLEMENT_FORWARD_XTYPEPROVIDER2( EventListener, EventListener_BASE, OPropertyContainer ) + +// OPropertySetHelper + +::cppu::IPropertyArrayHelper& +EventListener::getInfoHelper( ) +{ + return *getArrayHelper(); +} + +// OPropertyArrayUsageHelper + +::cppu::IPropertyArrayHelper* +EventListener::createArrayHelper( ) const +{ + Sequence< beans::Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); +} + +// XPropertySet +Reference< beans::XPropertySetInfo > +EventListener::getPropertySetInfo( ) throw (RuntimeException) +{ + Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +//liuchen 2009-6-23 +//decide if the control should execute the event +bool ApproveAll(const ScriptEvent&, void* ) +{ + return true; +} + +//for the given control type in evt.Arguments[0], look for if it appears in the type list in pPara +bool FindControl(const ScriptEvent& evt, void* pPara) +{ + lang::EventObject aEvent; + evt.Arguments[ 0 ] >>= aEvent; + uno::Reference< uno::XInterface > xInterface( aEvent.Source, uno::UNO_QUERY ); + + TypeList* pTypeListInfo = static_cast<TypeList*>(pPara); + Type* pType = pTypeListInfo->pTypeList; + int nLen = pTypeListInfo->nListLength; + + for (int i = 0; i < nLen; i++) + { + if ( xInterface->queryInterface( *pType ).hasValue() ) + { + return true; + } + pType++; + } + + return false; +} + +//if the the given control type in evt.Arguments[0] appears in the type list in pPara, then approve the execution +bool ApproveType(const ScriptEvent& evt, void* pPara) +{ + return FindControl(evt, pPara); +} + +//if the the given control type in evt.Arguments[0] appears in the type list in pPara, then deny the execution +bool DenyType(const ScriptEvent& evt, void* pPara) +{ + return !FindControl(evt, pPara); +} + +//when mouse is moving, either the mouse button is pressed or some key is pressed can trigger the OO mouseDragged event, +//the former should be denyed, and the latter allowed, only by doing so can the VBA MouseMove event when the "Shift" key is +//pressed can be correctly triggered +bool DenyMouseDrag(const ScriptEvent& evt, void* ) +{ + awt::MouseEvent aEvent; + evt.Arguments[ 0 ] >>= aEvent; + if (aEvent.Buttons == 0 ) + { + return true; + } + else + { + return false; + } +} + + + +//liuchen 2009-6-23 +// EventListener + +void +EventListener::firing_Impl(const ScriptEvent& evt, Any* /*pRet*/ ) throw(RuntimeException) +{ + OSL_TRACE("EventListener::firing_Impl( FAKE VBA_EVENTS )"); + static const ::rtl::OUString vbaInterOp = + ::rtl::OUString::createFromAscii("VBAInterop"); + + // let default handlers deal with non vba stuff + if ( !evt.ScriptType.equals( vbaInterOp ) ) + return; + lang::EventObject aEvent; + evt.Arguments[ 0 ] >>= aEvent; + OSL_TRACE("Argument[0] is %s", rtl::OUStringToOString( comphelper::anyToString( evt.Arguments[0] ), RTL_TEXTENCODING_UTF8 ).getStr() ); + OSL_TRACE("Getting Control"); + uno::Reference< awt::XControl > xControl( aEvent.Source, uno::UNO_QUERY_THROW ); + OSL_TRACE("Getting properties"); + uno::Reference< beans::XPropertySet > xProps( xControl->getModel(), uno::UNO_QUERY_THROW ); + + rtl::OUString sName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm") ); + OSL_TRACE("Getting Name"); + + uno::Reference< awt::XDialog > xDlg( aEvent.Source, uno::UNO_QUERY ); + if ( !xDlg.is() ) + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Name") ) ) >>= sName; + //dumpEvent( evt ); + EventInfoHash& infos = getEventTransInfo(); + EventInfoHash::const_iterator eventInfo_it = infos.find( evt.MethodName ); + EventInfoHash::const_iterator it_end = infos.end(); + if ( eventInfo_it == it_end ) + { + OSL_TRACE("Bogus event for %s", + rtl::OUStringToOString( evt.ScriptType, RTL_TEXTENCODING_UTF8 ).getStr() ); + return; + } + + uno::Reference< script::provider::XScriptProviderSupplier > xSPS( m_xModel, uno::UNO_QUERY ); + uno::Reference< script::provider::XScriptProvider > xScriptProvider; + if ( xSPS.is() ) + xScriptProvider = xSPS->getScriptProvider(); + if ( xScriptProvider.is() && mpShell ) + { + std::list< TranslateInfo > matchingMethods; + std::list< TranslateInfo >::const_iterator txInfo = + eventInfo_it->second.begin(); + std::list< TranslateInfo >::const_iterator txInfo_end = eventInfo_it->second.end(); + rtl::OUString sMacroLoc = rtl::OUString::createFromAscii("Standard.").concat( evt.ScriptCode ).concat( rtl::OUString::createFromAscii(".") ); + + StarBASIC* pBasic = mpShell->GetBasic(); + SbModule* pModule = pBasic->FindModule( evt.ScriptCode ); + for ( ; pModule && txInfo != txInfo_end; ++txInfo ) + { + // see if we have a match for the handlerextension + // where ScriptCode is methodname_handlerextension + rtl::OUString sTemp = sName.concat( (*txInfo).sVBAName ); + + OSL_TRACE("*** trying to invoke %s ", + rtl::OUStringToOString( sTemp, RTL_TEXTENCODING_UTF8 ).getStr() ); + SbMethod* pMeth = static_cast< SbMethod* >( pModule->Find( sTemp, SbxCLASS_METHOD ) ); + if ( pMeth ) + { + //liuchen 2009-6-8 + if (! txInfo->ApproveRule(evt, txInfo->pPara) ) + { + continue; + } + //liuchen 2009-6-8 + // !! translate arguments & emulate events where necessary + Sequence< Any > aArguments; + if ( (*txInfo).toVBA ) + aArguments = (*txInfo).toVBA( evt.Arguments ); + else + aArguments = evt.Arguments; + if ( aArguments.getLength() ) + { + // call basic event handlers for event + + static rtl::OUString part1 = rtl::OUString::createFromAscii( "vnd.sun.star.script:"); + static rtl::OUString part2 = rtl::OUString::createFromAscii("?language=Basic&location=document"); + + // create script url + rtl::OUString url = part1 + sMacroLoc + sTemp + part2; + + OSL_TRACE("script url = %s", + rtl::OUStringToOString( url, + RTL_TEXTENCODING_UTF8 ).getStr() ); + Sequence< sal_Int16 > aOutArgsIndex; + Sequence< Any > aOutArgs; + try + { + if ( mpShell ) + { + uno::Any aRet; + mpShell->CallXScript( url, + aArguments, aRet, aOutArgsIndex, aOutArgs, false ); + } + } + catch ( uno::Exception& e ) + { + OSL_TRACE("event script raised %s", rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } + } + } +} + +typedef ::cppu::WeakImplHelper1< XVBAToOOEventDescGen > VBAToOOEventDescGen_BASE; + + +class VBAToOOEventDescGen : public VBAToOOEventDescGen_BASE +{ +public: + VBAToOOEventDescGen( const Reference< XComponentContext >& rxContext ); + + // XVBAToOOEventDescGen + virtual Sequence< ScriptEventDescriptor > SAL_CALL getEventDescriptions( const Reference< XInterface >& control, const rtl::OUString& sCodeName ) throw (RuntimeException); + virtual Reference< XScriptEventsSupplier > SAL_CALL getEventSupplier( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (::com::sun::star::uno::RuntimeException); +private: + Reference< XComponentContext > m_xContext; + +}; + +VBAToOOEventDescGen::VBAToOOEventDescGen( const Reference< XComponentContext >& rxContext ):m_xContext( rxContext ) {} + +Sequence< ScriptEventDescriptor > SAL_CALL +VBAToOOEventDescGen::getEventDescriptions( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (RuntimeException) +{ + ScriptEventHelper evntHelper( xControl ); + return evntHelper.createEvents( sCodeName ); +} + +Reference< XScriptEventsSupplier > SAL_CALL +VBAToOOEventDescGen::getEventSupplier( const Reference< XInterface >& xControl, const rtl::OUString& sCodeName ) throw (::com::sun::star::uno::RuntimeException) +{ + ScriptEventHelper evntHelper( xControl ); + Reference< XScriptEventsSupplier > xSupplier = + new ReadOnlyEventsSupplier( + evntHelper.getEventListeners(), sCodeName ) ; + return xSupplier; +} + +// Component related + +namespace evtlstner +{ + ::rtl::OUString SAL_CALL getImplementationName() + { + static ::rtl::OUString* pImplName = 0; + if ( !pImplName ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pImplName ) + { + static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.EventListener" ) ); + pImplName = &aImplName; + } + } + return *pImplName; + } + + uno::Reference< XInterface > SAL_CALL create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) + { + return static_cast< lang::XTypeProvider * >( new EventListener( xContext ) ); + } + + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + { + const ::rtl::OUString strName( ::evtlstner::getImplementationName() ); + return Sequence< ::rtl::OUString >( &strName, 1 ); + } +} +namespace ooevtdescgen +{ + ::rtl::OUString SAL_CALL getImplementationName() + { + static ::rtl::OUString* pImplName = 0; + if ( !pImplName ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pImplName ) + { + static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAToOOEventDesc" ) ); + pImplName = &aImplName; + } + } + return *pImplName; + } + + uno::Reference< XInterface > SAL_CALL create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ) + { + return static_cast< lang::XTypeProvider * >( new VBAToOOEventDescGen( xContext ) ); + } + + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + { + const ::rtl::OUString strName( ::ooevtdescgen::getImplementationName() ); + return Sequence< ::rtl::OUString >( &strName, 1 ); + } +} diff --git a/scripting/source/vbaevents/makefile.mk b/scripting/source/vbaevents/makefile.mk new file mode 100644 index 000000000000..1946c61d1e0b --- /dev/null +++ b/scripting/source/vbaevents/makefile.mk @@ -0,0 +1,93 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.0 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=scripting +TARGET=vbaevents +.IF "$(ENABLE_VBA)"!="YES" +dummy: + @echo "not building vbaevents..." +.ENDIF + +VISIBILITY_HIDDEN=TRUE +NO_BSYMBOLIC= TRUE +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +COMPRDB=$(SOLARBINDIR)$/types.rdb + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +#.INCLUDE : ..$/cppumaker.mk + +SLOFILES= \ + $(SLO)$/service.obj \ + $(SLO)$/eventhelper.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX).uno +SHL1IMPLIB= i$(TARGET) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(BASICLIB) \ + $(COMPHELPERLIB) \ + $(SFXLIB) \ + $(CPPULIB) \ + $(TOOLSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1LIBS=$(SLB)$/$(TARGET).lib + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +# ------------------------------------------------------------------ + +ALLTAR : \ + $(MISC)$/$(TARGET).don \ + +$(SLOFILES) : $(MISC)$/$(TARGET).don + +$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb + +$(CPPUMAKER) -O$(INCCOM)$/$(TARGET) -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@ + echo $@ + diff --git a/scripting/source/vbaevents/service.cxx b/scripting/source/vbaevents/service.cxx new file mode 100755 index 000000000000..9f38acb7e2a6 --- /dev/null +++ b/scripting/source/vbaevents/service.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: service.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_scripting.hxx" +#include "cppuhelper/implementationentry.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/registry/XRegistryKey.hpp" + +// ============================================================================= +// component exports +// ============================================================================= +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace evtlstner +{ + // ============================================================================= + // component operations + // ============================================================================= + + uno::Reference< XInterface > SAL_CALL create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ); + + // ----------------------------------------------------------------------------- + + ::rtl::OUString SAL_CALL getImplementationName(); + + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(); + + Reference<XInterface> SAL_CALL create( + Sequence<Any> const &, Reference<XComponentContext> const & ); +} // end evtlstner + +namespace ooevtdescgen +{ + // ============================================================================= + // component operations + // ============================================================================= + + uno::Reference< XInterface > SAL_CALL create( + Reference< XComponentContext > const & xContext ) + SAL_THROW( () ); + + // ----------------------------------------------------------------------------- + + ::rtl::OUString SAL_CALL getImplementationName(); + + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(); + + Reference<XInterface> SAL_CALL create( + Sequence<Any> const &, Reference<XComponentContext> const & ); +} // end ooevtdescgen + + + + // ============================================================================= + + const ::cppu::ImplementationEntry s_component_entries [] = + { + { + ::evtlstner::create, ::evtlstner::getImplementationName, + ::evtlstner::getSupportedServiceNames, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { + ::ooevtdescgen::create, ::ooevtdescgen::getImplementationName, + ::ooevtdescgen::getSupportedServiceNames, + ::cppu::createSingleComponentFactory, + 0, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; + +extern "C" +{ + SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) + { + OSL_TRACE("In component_getImplementationEnv"); + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + } + + SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + lang::XMultiServiceFactory * pServiceManager, registry::XRegistryKey * pRegistryKey ) + { + OSL_TRACE("In component_writeInfo"); + if ( ::cppu::component_writeInfoHelper( + pServiceManager, pRegistryKey, s_component_entries ) ) + return sal_True; + return sal_False; + } + + SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, + registry::XRegistryKey * pRegistryKey ) + { + OSL_TRACE("In component_getFactory"); + return ::cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, s_component_entries ); + } +} diff --git a/scripting/source/vbaevents/vbaevents.xml b/scripting/source/vbaevents/vbaevents.xml new file mode 100755 index 000000000000..f0e47a69da6f --- /dev/null +++ b/scripting/source/vbaevents/vbaevents.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name>vbaevents</module-name> + + <component-description> + <author>Noel Power </author> + <name>ooo.vba.EventListener</name> + <description>Event listener to handle ooo events and to translate them to calls to basic macros ala Button_Click etc.</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="drafts"/> + <supported-service>ooo.vba.EventListener</supported-service> + <type>com.sun.star.uno.XComponentContext</type> + </component-description> + + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> + +</module-description> |