/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ #ifdef AIX #define _LINUX_SOURCE_COMPAT #include #undef _LINUX_SOURCE_COMPAT #endif #ifdef WNT #include #include #undef OPTIONAL #endif #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star::io; using namespace com::sun::star::frame; namespace ext_plug { class FileSink : public ::cppu::WeakAggImplHelper1< ::com::sun::star::io::XOutputStream > { private: Reference< ::com::sun::star::uno::XComponentContext > m_xContext; FILE* fp; Reference< ::com::sun::star::plugin::XPlugin > m_xPlugin; OUString m_aMIMEType; OUString m_aTarget; OUString m_aFileName; public: FileSink( const Reference< ::com::sun::star::uno::XComponentContext > &, const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& mimetype, const OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source ); virtual ~FileSink(); // ::com::sun::star::io::XOutputStream virtual void SAL_CALL writeBytes( const Sequence& ) throw(std::exception) SAL_OVERRIDE; virtual void SAL_CALL flush() throw(std::exception) SAL_OVERRIDE; virtual void SAL_CALL closeOutput() throw(std::exception) SAL_OVERRIDE; }; } using namespace ext_plug; class XPluginContext_Impl : public ::cppu::WeakAggImplHelper1< ::com::sun::star::plugin::XPluginContext > { Reference< ::com::sun::star::uno::XComponentContext > m_xContext; rtl_TextEncoding m_aEncoding; public: XPluginContext_Impl( const Reference< ::com::sun::star::uno::XComponentContext > & ); virtual ~XPluginContext_Impl(); virtual OUString SAL_CALL getValue(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, ::com::sun::star::plugin::PluginVariable variable) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL getURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Reference< ::com::sun::star::lang::XEventListener > & listener) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL getURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL postURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file, const Reference< ::com::sun::star::lang::XEventListener > & listener) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL postURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL newStream(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& mimetype, const OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual void SAL_CALL displayStatusText(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& message) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; virtual OUString SAL_CALL getUserAgent(const Reference< ::com::sun::star::plugin::XPlugin > & plugin) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) SAL_OVERRIDE; }; Reference< ::com::sun::star::plugin::XPluginContext > XPluginManager_Impl::createPluginContext() throw(std::exception) { return new XPluginContext_Impl( m_xContext ); } XPluginContext_Impl::XPluginContext_Impl( const Reference< ::com::sun::star::uno::XComponentContext > & rxContext ) : m_xContext( rxContext ), m_aEncoding( osl_getThreadTextEncoding() ) { } XPluginContext_Impl::~XPluginContext_Impl() { } OUString XPluginContext_Impl::getValue( const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/, ::com::sun::star::plugin::PluginVariable /*variable*/ ) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { return OUString(); } void XPluginContext_Impl::getURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { Reference< XDesktop2 > xDesktop = Desktop::create(m_xContext); if( target.isEmpty() ) { INetURLObject aURL; aURL.SetSmartProtocol( INET_PROT_FILE ); aURL.SetSmartURL( url ); OUString aUrl = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI); // the mimetype cannot be specified plugin->provideNewStream( OUString(), Reference< XActiveDataSource >(), aUrl, 0, 0, aUrl.startsWith("file:") ); return; } XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( plugin ); if( pPlugin ) { try { ::com::sun::star::beans::PropertyValue aValue; aValue.Name = "Referer"; aValue.Value <<= pPlugin->getRefererURL(); Sequence< ::com::sun::star::beans::PropertyValue > aArgs( &aValue, 1 ); Reference< ::com::sun::star::lang::XComponent > xComp = xDesktop->loadComponentFromURL( url, target, ::com::sun::star::frame::FrameSearchFlag::PARENT | ::com::sun::star::frame::FrameSearchFlag::SELF | ::com::sun::star::frame::FrameSearchFlag::CHILDREN | ::com::sun::star::frame::FrameSearchFlag::SIBLINGS | ::com::sun::star::frame::FrameSearchFlag::TASKS | ::com::sun::star::frame::FrameSearchFlag::CREATE, aArgs ); } catch(...) { throw ::com::sun::star::plugin::PluginException(); } } } void XPluginContext_Impl::getURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Reference< ::com::sun::star::lang::XEventListener > & listener ) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { getURL( plugin, url, target ); if( listener.is() ) listener->disposing( ::com::sun::star::lang::EventObject() ); } OUString XPluginContext_Impl::getUserAgent(const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { return OUString("Mozilla 3.0"); } void XPluginContext_Impl::displayStatusText(const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/, const OUString& /*message*/) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { } void XPluginContext_Impl::postURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { Sequence< sal_Int8 > aBuf; if( file ) { OUString aFileName( (char*)buf.getConstArray(), strlen((char*)buf.getConstArray()), m_aEncoding ); INetURLObject aFilePath( aFileName ); aFileName = aFilePath.PathToFileName(); SvFileStream aStream( aFileName, STREAM_READ ); if( aStream.IsOpen() ) { sal_Int64 const nBytes = aStream.remainingSize(); aBuf = Sequence( nBytes ); aStream.Read( aBuf.getArray(), nBytes ); aStream.Close(); osl::FileBase::getFileURLFromSystemPath( aFileName, aFileName ); osl::File::remove( aFileName ); } } Reference< XDesktop2 > xDesktop = Desktop::create(m_xContext); XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( plugin ); if( pPlugin ) { try { ::com::sun::star::beans::PropertyValue aValues[2]; aValues[0].Name = "Referer"; aValues[0].Value <<= pPlugin->getRefererURL(); aValues[1].Name = "PostString"; aValues[1].Value <<= OStringToOUString( (char*)( file ? aBuf : buf ).getConstArray(), m_aEncoding ); Sequence< ::com::sun::star::beans::PropertyValue > aArgs( aValues, 2 ); Reference< ::com::sun::star::lang::XComponent > xComp = xDesktop->loadComponentFromURL( url, target, ::com::sun::star::frame::FrameSearchFlag::PARENT | ::com::sun::star::frame::FrameSearchFlag::SELF | ::com::sun::star::frame::FrameSearchFlag::CHILDREN | ::com::sun::star::frame::FrameSearchFlag::SIBLINGS | ::com::sun::star::frame::FrameSearchFlag::TASKS | ::com::sun::star::frame::FrameSearchFlag::CREATE, aArgs ); } catch( ... ) { throw ::com::sun::star::plugin::PluginException(); } } } void XPluginContext_Impl::postURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& url, const OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file, const Reference< ::com::sun::star::lang::XEventListener > & listener ) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { postURL( plugin, url, target, buf, file ); if( listener.is() ) listener->disposing( ::com::sun::star::lang::EventObject() ); } void XPluginContext_Impl::newStream( const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& mimetype, const OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source ) throw( ::com::sun::star::plugin::PluginException, RuntimeException, std::exception ) { FileSink* pNewSink = new FileSink( m_xContext, plugin, mimetype, target, source ); pNewSink->acquire(); } FileSink::FileSink( const Reference< ::com::sun::star::uno::XComponentContext > & rxContext, const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const OUString& mimetype, const OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source ) : m_xContext( rxContext ), m_xPlugin( plugin ), m_aMIMEType( mimetype ), m_aTarget( target ) { osl::FileBase::createTempFile( 0, 0, &m_aFileName ); OString aFile = OUStringToOString( m_aFileName, osl_getThreadTextEncoding() ); fp = fopen( aFile.getStr() , "wb" ); Reference< ::com::sun::star::io::XActiveDataControl > xControl( source, UNO_QUERY ); source->setOutputStream( Reference< ::com::sun::star::io::XOutputStream > ( this ) ); if( xControl.is() ) xControl->start(); } FileSink::~FileSink() { osl::File::remove( m_aFileName ); } void FileSink::closeOutput() throw(std::exception) { if( fp ) fclose( fp ); Reference< XDesktop2 > xDesktop = Desktop::create(m_xContext); XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( m_xPlugin ); if( pPlugin ) { try { ::com::sun::star::beans::PropertyValue aValue; aValue.Name = "Referer"; aValue.Value <<= pPlugin->getRefererURL(); Sequence< ::com::sun::star::beans::PropertyValue > aArgs( &aValue, 1 ); Reference< ::com::sun::star::lang::XComponent > xComp = xDesktop->loadComponentFromURL( m_aFileName, m_aTarget, ::com::sun::star::frame::FrameSearchFlag::PARENT | ::com::sun::star::frame::FrameSearchFlag::SELF | ::com::sun::star::frame::FrameSearchFlag::CHILDREN | ::com::sun::star::frame::FrameSearchFlag::SIBLINGS | ::com::sun::star::frame::FrameSearchFlag::TASKS | ::com::sun::star::frame::FrameSearchFlag::CREATE, aArgs ); } catch( ... ) { } } release(); } void FileSink::writeBytes( const Sequence& Buffer ) throw(std::exception) { if( fp ) { size_t nItems = Buffer.getLength(); bool bSuccess = (fwrite(Buffer.getConstArray(), 1, nItems, fp) == nItems); SAL_WARN_IF( !bSuccess, "extensions.plugin", "short write"); } } void FileSink::flush() throw(std::exception) { if( fp ) fflush( fp ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */