1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/security.hxx>
21 #include <osl/file.hxx>
22 #include <osl/socket.h>
23 #include <cppuhelper/queryinterface.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <com/sun/star/beans/PropertyAttribute.hpp>
26 #include <com/sun/star/ucb/FileSystemNotation.hpp>
27 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
28 #include <cppuhelper/supportsservice.hxx>
29 #include "filglob.hxx"
31 #include "filtask.hxx"
35 using namespace fileaccess
;
36 using namespace com::sun::star
;
37 using namespace com::sun::star::uno
;
38 using namespace com::sun::star::lang
;
39 using namespace com::sun::star::beans
;
40 using namespace com::sun::star::ucb
;
41 using namespace com::sun::star::container
;
43 #if OSL_DEBUG_LEVEL > 0
44 #define THROW_WHERE SAL_WHERE
46 #define THROW_WHERE ""
50 /****************************************************************************/
56 /****************************************************************************/
57 FileProvider::FileProvider( const Reference
< XComponentContext
>& rxContext
)
58 : m_xContext(rxContext
)
59 , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION
)
63 FileProvider::~FileProvider()
68 void FileProvider::init()
71 m_pMyShell
.reset( new TaskManager( m_xContext
, this, true ) );
76 FileProvider::initialize(
77 const Sequence
< Any
>& aArguments
)
81 if( aArguments
.hasElements() &&
82 (aArguments
[0] >>= config
) &&
83 config
== "NoConfig" )
84 m_pMyShell
.reset( new TaskManager( m_xContext
, this, false ) );
86 m_pMyShell
.reset( new TaskManager( m_xContext
, this, true ) );
90 // XServiceInfo methods.
92 FileProvider::getImplementationName()
94 return "com.sun.star.comp.ucb.FileProvider";
97 sal_Bool SAL_CALL
FileProvider::supportsService(const OUString
& ServiceName
)
99 return cppu::supportsService(this, ServiceName
);
102 Sequence
< OUString
> SAL_CALL
103 FileProvider::getSupportedServiceNames()
105 return { "com.sun.star.ucb.FileContentProvider" };
111 Reference
< XContent
> SAL_CALL
112 FileProvider::queryContent(
113 const Reference
< XContentIdentifier
>& xIdentifier
)
117 bool err
= fileaccess::TaskManager::getUnqFromUrl( xIdentifier
->getContentIdentifier(),
122 throw IllegalIdentifierException( THROW_WHERE
);
125 return Reference
< XContent
>( new BaseContent( m_pMyShell
.get(), xIdentifier
, aUnc
) );
130 FileProvider::compareContentIds(
131 const Reference
< XContentIdentifier
>& Id1
,
132 const Reference
< XContentIdentifier
>& Id2
)
135 OUString aUrl1
= Id1
->getContentIdentifier();
136 OUString aUrl2
= Id2
->getContentIdentifier();
138 sal_Int32 iComp
= aUrl1
.compareTo( aUrl2
);
142 OUString aPath1
, aPath2
;
144 fileaccess::TaskManager::getUnqFromUrl( aUrl1
, aPath1
);
145 fileaccess::TaskManager::getUnqFromUrl( aUrl2
, aPath2
);
147 osl::FileBase::RC error
;
148 osl::DirectoryItem aItem1
, aItem2
;
150 error
= osl::DirectoryItem::get( aPath1
, aItem1
);
151 if ( error
== osl::FileBase::E_None
)
152 error
= osl::DirectoryItem::get( aPath2
, aItem2
);
154 if ( error
!= osl::FileBase::E_None
)
157 osl::FileStatus
aStatus1( osl_FileStatus_Mask_FileURL
);
158 osl::FileStatus
aStatus2( osl_FileStatus_Mask_FileURL
);
159 error
= aItem1
.getFileStatus( aStatus1
);
160 if ( error
== osl::FileBase::E_None
)
161 error
= aItem2
.getFileStatus( aStatus2
);
163 if ( error
== osl::FileBase::E_None
)
165 iComp
= aStatus1
.getFileURL().compareTo( aStatus2
.getFileURL() );
167 // Quick hack for Windows to threat all file systems as case insensitive
171 error
= osl::FileBase::getSystemPathFromFileURL( aStatus1
.getFileURL(), aPath1
);
172 if ( error
== osl::FileBase::E_None
)
173 error
= osl::FileBase::getSystemPathFromFileURL( aStatus2
.getFileURL(), aPath2
);
175 if ( error
== osl::FileBase::E_None
)
176 iComp
= aPath1
.compareToIgnoreAsciiCase( aPath2
);
186 Reference
< XContentIdentifier
> SAL_CALL
187 FileProvider::createContentIdentifier(
188 const OUString
& ContentId
)
191 return new FileContentIdentifier( ContentId
,false );
195 //XPropertySetInfoImpl
199 class XPropertySetInfoImpl2
200 : public cppu::OWeakObject
,
201 public XPropertySetInfo
204 XPropertySetInfoImpl2();
208 queryInterface( const Type
& aType
) override
;
210 virtual void SAL_CALL
214 virtual void SAL_CALL
219 virtual Sequence
< Property
> SAL_CALL
220 getProperties() override
;
222 virtual Property SAL_CALL
223 getPropertyByName( const OUString
& aName
) override
;
225 virtual sal_Bool SAL_CALL
226 hasPropertyByName( const OUString
& Name
) override
;
230 Sequence
< Property
> m_seq
;
235 XPropertySetInfoImpl2::XPropertySetInfoImpl2()
236 : m_seq
{ Property( "HostName",
238 cppu::UnoType
<OUString
>::get(),
239 PropertyAttribute::READONLY
),
240 Property( "HomeDirectory",
242 cppu::UnoType
<OUString
>::get(),
243 PropertyAttribute::READONLY
),
244 Property( "FileSystemNotation",
246 cppu::UnoType
<sal_Int32
>::get(),
247 PropertyAttribute::READONLY
)}
252 XPropertySetInfoImpl2::acquire()
255 OWeakObject::acquire();
260 XPropertySetInfoImpl2::release()
263 OWeakObject::release();
268 XPropertySetInfoImpl2::queryInterface( const Type
& rType
)
270 Any aRet
= cppu::queryInterface( rType
,
271 static_cast< XPropertySetInfo
* >(this) );
272 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
277 XPropertySetInfoImpl2::getPropertyByName( const OUString
& aName
)
279 auto pProp
= std::find_if(std::cbegin(m_seq
), std::cend(m_seq
),
280 [&aName
](const Property
& rProp
) { return rProp
.Name
== aName
; });
281 if (pProp
!= std::cend(m_seq
))
284 throw UnknownPropertyException( aName
);
288 Sequence
< Property
> SAL_CALL
289 XPropertySetInfoImpl2::getProperties()
296 XPropertySetInfoImpl2::hasPropertyByName(
297 const OUString
& aName
)
299 return std::any_of(std::cbegin(m_seq
), std::cend(m_seq
),
300 [&aName
](const Property
& rProp
) { return rProp
.Name
== aName
; });
304 void FileProvider::initProperties()
306 std::scoped_lock
aGuard( m_aMutex
);
307 if( m_xPropertySetInfo
.is() )
310 osl_getLocalHostname( &m_HostName
.pData
);
313 m_FileSystemNotation
= FileSystemNotation::UNIX_NOTATION
;
314 #elif defined( _WIN32 )
315 m_FileSystemNotation
= FileSystemNotation::DOS_NOTATION
;
317 m_FileSystemNotation
= FileSystemNotation::UNKNOWN_NOTATION
;
319 osl::Security aSecurity
;
320 aSecurity
.getHomeDir( m_HomeDirectory
);
322 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
323 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
324 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
325 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
327 m_xPropertySetInfo
= new XPropertySetInfoImpl2();
333 Reference
< XPropertySetInfo
> SAL_CALL
334 FileProvider::getPropertySetInfo( )
337 return m_xPropertySetInfo
;
342 FileProvider::setPropertyValue( const OUString
& aPropertyName
,
345 if( !(aPropertyName
== "FileSystemNotation" ||
346 aPropertyName
== "HomeDirectory" ||
347 aPropertyName
== "HostName") )
348 throw UnknownPropertyException( aPropertyName
);
353 FileProvider::getPropertyValue(
354 const OUString
& aPropertyName
)
357 if( aPropertyName
== "FileSystemNotation" )
359 return Any(m_FileSystemNotation
);
361 else if( aPropertyName
== "HomeDirectory" )
363 return Any(m_HomeDirectory
);
365 else if( aPropertyName
== "HostName" )
367 return Any(m_HostName
);
370 throw UnknownPropertyException( aPropertyName
);
375 FileProvider::addPropertyChangeListener(
377 const Reference
< XPropertyChangeListener
>& )
383 FileProvider::removePropertyChangeListener(
385 const Reference
< XPropertyChangeListener
>& )
390 FileProvider::addVetoableChangeListener(
392 const Reference
< XVetoableChangeListener
>& )
398 FileProvider::removeVetoableChangeListener(
400 const Reference
< XVetoableChangeListener
>& )
405 // XFileIdentifierConverter
408 FileProvider::getFileProviderLocality( const OUString
& BaseURL
)
410 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
411 // return -1 (mismatch). What is missing is a fast comparison to ASCII,
413 return BaseURL
.getLength() >= 5
414 && (BaseURL
[0] == 'F' || BaseURL
[0] == 'f')
415 && (BaseURL
[1] == 'I' || BaseURL
[1] == 'i')
416 && (BaseURL
[2] == 'L' || BaseURL
[2] == 'l')
417 && (BaseURL
[3] == 'E' || BaseURL
[3] == 'e')
418 && BaseURL
[4] == ':' ?
422 OUString SAL_CALL
FileProvider::getFileURLFromSystemPath( const OUString
&,
423 const OUString
& SystemPath
)
425 OUString aNormalizedPath
;
426 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath
,aNormalizedPath
) != osl::FileBase::E_None
)
429 return aNormalizedPath
;
432 OUString SAL_CALL
FileProvider::getSystemPathFromFileURL( const OUString
& URL
)
434 OUString aSystemPath
;
435 if (osl::FileBase::getSystemPathFromFileURL( URL
,aSystemPath
) != osl::FileBase::E_None
)
441 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
442 ucb_file_FileProvider_get_implementation(
443 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
445 return cppu::acquire(new FileProvider(context
));
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */