diff options
Diffstat (limited to 'ucb/source/ucp/file/prov.cxx')
-rw-r--r-- | ucb/source/ucp/file/prov.cxx | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/ucb/source/ucp/file/prov.cxx b/ucb/source/ucp/file/prov.cxx new file mode 100644 index 000000000..eab4ec530 --- /dev/null +++ b/ucb/source/ucp/file/prov.cxx @@ -0,0 +1,447 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <osl/security.hxx> +#include <osl/file.hxx> +#include <osl/socket.h> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/ucb/FileSystemNotation.hpp> +#include <com/sun/star/ucb/IllegalIdentifierException.hpp> +#include <cppuhelper/supportsservice.hxx> +#include "filglob.hxx" +#include "filid.hxx" +#include "filtask.hxx" +#include "bc.hxx" +#include "prov.hxx" + +using namespace fileaccess; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::ucb; +using namespace com::sun::star::container; + +#if OSL_DEBUG_LEVEL > 0 +#define THROW_WHERE SAL_WHERE +#else +#define THROW_WHERE "" +#endif + + +/****************************************************************************/ +/* */ +/* */ +/* FileProvider */ +/* */ +/* */ +/****************************************************************************/ +FileProvider::FileProvider( const Reference< XComponentContext >& rxContext ) + : m_xContext(rxContext) + , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION) +{ +} + +FileProvider::~FileProvider() +{ +} + +// XInitialization +void FileProvider::init() +{ + if( ! m_pMyShell ) + m_pMyShell.reset( new TaskManager( m_xContext, this, true ) ); +} + + +void SAL_CALL +FileProvider::initialize( + const Sequence< Any >& aArguments ) +{ + if( ! m_pMyShell ) { + OUString config; + if( aArguments.hasElements() && + (aArguments[0] >>= config) && + config == "NoConfig" ) + m_pMyShell.reset( new TaskManager( m_xContext, this, false ) ); + else + m_pMyShell.reset( new TaskManager( m_xContext, this, true ) ); + } +} + +// XServiceInfo methods. +OUString SAL_CALL +FileProvider::getImplementationName() +{ + return "com.sun.star.comp.ucb.FileProvider"; +} + +sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString > SAL_CALL +FileProvider::getSupportedServiceNames() +{ + return { "com.sun.star.ucb.FileContentProvider" }; +} + +// XContent + + +Reference< XContent > SAL_CALL +FileProvider::queryContent( + const Reference< XContentIdentifier >& xIdentifier ) +{ + init(); + OUString aUnc; + bool err = fileaccess::TaskManager::getUnqFromUrl( xIdentifier->getContentIdentifier(), + aUnc ); + + if( err ) + { + throw IllegalIdentifierException( THROW_WHERE ); + } + + return Reference< XContent >( new BaseContent( m_pMyShell.get(), xIdentifier, aUnc ) ); +} + + +sal_Int32 SAL_CALL +FileProvider::compareContentIds( + const Reference< XContentIdentifier >& Id1, + const Reference< XContentIdentifier >& Id2 ) +{ + init(); + OUString aUrl1 = Id1->getContentIdentifier(); + OUString aUrl2 = Id2->getContentIdentifier(); + + sal_Int32 iComp = aUrl1.compareTo( aUrl2 ); + + if ( 0 != iComp ) + { + OUString aPath1, aPath2; + + fileaccess::TaskManager::getUnqFromUrl( aUrl1, aPath1 ); + fileaccess::TaskManager::getUnqFromUrl( aUrl2, aPath2 ); + + osl::FileBase::RC error; + osl::DirectoryItem aItem1, aItem2; + + error = osl::DirectoryItem::get( aPath1, aItem1 ); + if ( error == osl::FileBase::E_None ) + error = osl::DirectoryItem::get( aPath2, aItem2 ); + + if ( error != osl::FileBase::E_None ) + return iComp; + + osl::FileStatus aStatus1( osl_FileStatus_Mask_FileURL ); + osl::FileStatus aStatus2( osl_FileStatus_Mask_FileURL ); + error = aItem1.getFileStatus( aStatus1 ); + if ( error == osl::FileBase::E_None ) + error = aItem2.getFileStatus( aStatus2 ); + + if ( error == osl::FileBase::E_None ) + { + iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() ); + +// Quick hack for Windows to threat all file systems as case insensitive +#ifdef _WIN32 + if ( 0 != iComp ) + { + error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 ); + if ( error == osl::FileBase::E_None ) + error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 ); + + if ( error == osl::FileBase::E_None ) + iComp = aPath1.compareToIgnoreAsciiCase( aPath2 ); + } +#endif + } + } + + return iComp; +} + + +Reference< XContentIdentifier > SAL_CALL +FileProvider::createContentIdentifier( + const OUString& ContentId ) +{ + init(); + return new FileContentIdentifier( ContentId,false ); +} + + +//XPropertySetInfoImpl + +namespace { + +class XPropertySetInfoImpl2 + : public cppu::OWeakObject, + public XPropertySetInfo +{ +public: + XPropertySetInfoImpl2(); + + // XInterface + virtual Any SAL_CALL + queryInterface( const Type& aType ) override; + + virtual void SAL_CALL + acquire() + noexcept override; + + virtual void SAL_CALL + release() + noexcept override; + + + virtual Sequence< Property > SAL_CALL + getProperties() override; + + virtual Property SAL_CALL + getPropertyByName( const OUString& aName ) override; + + virtual sal_Bool SAL_CALL + hasPropertyByName( const OUString& Name ) override; + + +private: + Sequence< Property > m_seq; +}; + +} + +XPropertySetInfoImpl2::XPropertySetInfoImpl2() + : m_seq{ Property( "HostName", + -1, + cppu::UnoType<OUString>::get(), + PropertyAttribute::READONLY ), + Property( "HomeDirectory", + -1, + cppu::UnoType<OUString>::get(), + PropertyAttribute::READONLY ), + Property( "FileSystemNotation", + -1, + cppu::UnoType<sal_Int32>::get(), + PropertyAttribute::READONLY )} +{ +} + +void SAL_CALL +XPropertySetInfoImpl2::acquire() + noexcept +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XPropertySetInfoImpl2::release() + noexcept +{ + OWeakObject::release(); +} + + +Any SAL_CALL +XPropertySetInfoImpl2::queryInterface( const Type& rType ) +{ + Any aRet = cppu::queryInterface( rType, + static_cast< XPropertySetInfo* >(this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +Property SAL_CALL +XPropertySetInfoImpl2::getPropertyByName( const OUString& aName ) +{ + auto pProp = std::find_if(std::cbegin(m_seq), std::cend(m_seq), + [&aName](const Property& rProp) { return rProp.Name == aName; }); + if (pProp != std::cend(m_seq)) + return *pProp; + + throw UnknownPropertyException( aName ); +} + + +Sequence< Property > SAL_CALL +XPropertySetInfoImpl2::getProperties() +{ + return m_seq; +} + + +sal_Bool SAL_CALL +XPropertySetInfoImpl2::hasPropertyByName( + const OUString& aName ) +{ + return std::any_of(std::cbegin(m_seq), std::cend(m_seq), + [&aName](const Property& rProp) { return rProp.Name == aName; }); +} + + +void FileProvider::initProperties() +{ + std::scoped_lock aGuard( m_aMutex ); + if( m_xPropertySetInfo.is() ) + return; + + osl_getLocalHostname( &m_HostName.pData ); + +#if defined ( UNX ) + m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION; +#elif defined( _WIN32 ) + m_FileSystemNotation = FileSystemNotation::DOS_NOTATION; +#else + m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION; +#endif + osl::Security aSecurity; + aSecurity.getHomeDir( m_HomeDirectory ); + + // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0; + // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1; + // static const sal_Int32 DOS_NOTATION = (sal_Int32)2; + // static const sal_Int32 MAC_NOTATION = (sal_Int32)3; + + m_xPropertySetInfo = new XPropertySetInfoImpl2(); +} + + +// XPropertySet + +Reference< XPropertySetInfo > SAL_CALL +FileProvider::getPropertySetInfo( ) +{ + initProperties(); + return m_xPropertySetInfo; +} + + +void SAL_CALL +FileProvider::setPropertyValue( const OUString& aPropertyName, + const Any& ) +{ + if( !(aPropertyName == "FileSystemNotation" || + aPropertyName == "HomeDirectory" || + aPropertyName == "HostName") ) + throw UnknownPropertyException( aPropertyName ); +} + + +Any SAL_CALL +FileProvider::getPropertyValue( + const OUString& aPropertyName ) +{ + initProperties(); + if( aPropertyName == "FileSystemNotation" ) + { + return Any(m_FileSystemNotation); + } + else if( aPropertyName == "HomeDirectory" ) + { + return Any(m_HomeDirectory); + } + else if( aPropertyName == "HostName" ) + { + return Any(m_HostName); + } + else + throw UnknownPropertyException( aPropertyName ); +} + + +void SAL_CALL +FileProvider::addPropertyChangeListener( + const OUString&, + const Reference< XPropertyChangeListener >& ) +{ +} + + +void SAL_CALL +FileProvider::removePropertyChangeListener( + const OUString&, + const Reference< XPropertyChangeListener >& ) +{ +} + +void SAL_CALL +FileProvider::addVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) +{ +} + + +void SAL_CALL +FileProvider::removeVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) +{ +} + + +// XFileIdentifierConverter + +sal_Int32 SAL_CALL +FileProvider::getFileProviderLocality( const OUString& BaseURL ) +{ + // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise + // return -1 (mismatch). What is missing is a fast comparison to ASCII, + // ignoring case: + return BaseURL.getLength() >= 5 + && (BaseURL[0] == 'F' || BaseURL[0] == 'f') + && (BaseURL[1] == 'I' || BaseURL[1] == 'i') + && (BaseURL[2] == 'L' || BaseURL[2] == 'l') + && (BaseURL[3] == 'E' || BaseURL[3] == 'e') + && BaseURL[4] == ':' ? + 10 : -1; +} + +OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&, + const OUString& SystemPath ) +{ + OUString aNormalizedPath; + if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None ) + return OUString(); + + return aNormalizedPath; +} + +OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL ) +{ + OUString aSystemPath; + if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None ) + return OUString(); + + return aSystemPath; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +ucb_file_FileProvider_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new FileProvider(context)); +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |