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/factory.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include "filglob.hxx"
32 #include "filtask.hxx"
36 using namespace fileaccess
;
37 using namespace com::sun::star
;
38 using namespace com::sun::star::uno
;
39 using namespace com::sun::star::lang
;
40 using namespace com::sun::star::beans
;
41 using namespace com::sun::star::ucb
;
42 using namespace com::sun::star::container
;
44 #if OSL_DEBUG_LEVEL > 0
45 #define THROW_WHERE SAL_WHERE
47 #define THROW_WHERE ""
51 /****************************************************************************/
57 /****************************************************************************/
58 FileProvider::FileProvider( const Reference
< XComponentContext
>& rxContext
)
59 : m_xContext(rxContext
)
60 , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION
)
64 FileProvider::~FileProvider()
69 void FileProvider::init()
72 m_pMyShell
.reset( new TaskManager( m_xContext
, this, true ) );
77 FileProvider::initialize(
78 const Sequence
< Any
>& aArguments
)
82 if( aArguments
.hasElements() &&
83 (aArguments
[0] >>= config
) &&
84 config
== "NoConfig" )
85 m_pMyShell
.reset( new TaskManager( m_xContext
, this, false ) );
87 m_pMyShell
.reset( new TaskManager( m_xContext
, this, true ) );
91 // XServiceInfo methods.
93 FileProvider::getImplementationName()
95 return "com.sun.star.comp.ucb.FileProvider";
98 sal_Bool SAL_CALL
FileProvider::supportsService(const OUString
& ServiceName
)
100 return cppu::supportsService(this, ServiceName
);
103 Sequence
< OUString
> SAL_CALL
104 FileProvider::getSupportedServiceNames()
106 return { "com.sun.star.ucb.FileContentProvider" };
112 Reference
< XContent
> SAL_CALL
113 FileProvider::queryContent(
114 const Reference
< XContentIdentifier
>& xIdentifier
)
118 bool err
= fileaccess::TaskManager::getUnqFromUrl( xIdentifier
->getContentIdentifier(),
123 throw IllegalIdentifierException( THROW_WHERE
);
126 return Reference
< XContent
>( new BaseContent( m_pMyShell
.get(), xIdentifier
, aUnc
) );
131 FileProvider::compareContentIds(
132 const Reference
< XContentIdentifier
>& Id1
,
133 const Reference
< XContentIdentifier
>& Id2
)
136 OUString aUrl1
= Id1
->getContentIdentifier();
137 OUString aUrl2
= Id2
->getContentIdentifier();
139 sal_Int32 iComp
= aUrl1
.compareTo( aUrl2
);
143 OUString aPath1
, aPath2
;
145 fileaccess::TaskManager::getUnqFromUrl( aUrl1
, aPath1
);
146 fileaccess::TaskManager::getUnqFromUrl( aUrl2
, aPath2
);
148 osl::FileBase::RC error
;
149 osl::DirectoryItem aItem1
, aItem2
;
151 error
= osl::DirectoryItem::get( aPath1
, aItem1
);
152 if ( error
== osl::FileBase::E_None
)
153 error
= osl::DirectoryItem::get( aPath2
, aItem2
);
155 if ( error
!= osl::FileBase::E_None
)
158 osl::FileStatus
aStatus1( osl_FileStatus_Mask_FileURL
);
159 osl::FileStatus
aStatus2( osl_FileStatus_Mask_FileURL
);
160 error
= aItem1
.getFileStatus( aStatus1
);
161 if ( error
== osl::FileBase::E_None
)
162 error
= aItem2
.getFileStatus( aStatus2
);
164 if ( error
== osl::FileBase::E_None
)
166 iComp
= aStatus1
.getFileURL().compareTo( aStatus2
.getFileURL() );
168 // Quick hack for Windows to threat all file systems as case insensitive
172 error
= osl::FileBase::getSystemPathFromFileURL( aStatus1
.getFileURL(), aPath1
);
173 if ( error
== osl::FileBase::E_None
)
174 error
= osl::FileBase::getSystemPathFromFileURL( aStatus2
.getFileURL(), aPath2
);
176 if ( error
== osl::FileBase::E_None
)
177 iComp
= aPath1
.compareToIgnoreAsciiCase( aPath2
);
187 Reference
< XContentIdentifier
> SAL_CALL
188 FileProvider::createContentIdentifier(
189 const OUString
& ContentId
)
192 return new FileContentIdentifier( ContentId
,false );
196 //XPropertySetInfoImpl
200 class XPropertySetInfoImpl2
201 : public cppu::OWeakObject
,
202 public XPropertySetInfo
205 XPropertySetInfoImpl2();
209 queryInterface( const Type
& aType
) override
;
211 virtual void SAL_CALL
215 virtual void SAL_CALL
220 virtual Sequence
< Property
> SAL_CALL
221 getProperties() override
;
223 virtual Property SAL_CALL
224 getPropertyByName( const OUString
& aName
) override
;
226 virtual sal_Bool SAL_CALL
227 hasPropertyByName( const OUString
& Name
) override
;
231 Sequence
< Property
> m_seq
;
236 XPropertySetInfoImpl2::XPropertySetInfoImpl2()
239 m_seq
[0] = Property( "HostName",
241 cppu::UnoType
<OUString
>::get(),
242 PropertyAttribute::READONLY
);
244 m_seq
[1] = Property( "HomeDirectory",
246 cppu::UnoType
<OUString
>::get(),
247 PropertyAttribute::READONLY
);
249 m_seq
[2] = Property( "FileSystemNotation",
251 cppu::UnoType
<sal_Int32
>::get(),
252 PropertyAttribute::READONLY
);
256 XPropertySetInfoImpl2::acquire()
259 OWeakObject::acquire();
264 XPropertySetInfoImpl2::release()
267 OWeakObject::release();
272 XPropertySetInfoImpl2::queryInterface( const Type
& rType
)
274 Any aRet
= cppu::queryInterface( rType
,
275 static_cast< XPropertySetInfo
* >(this) );
276 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
281 XPropertySetInfoImpl2::getPropertyByName( const OUString
& aName
)
283 auto pProp
= std::find_if(m_seq
.begin(), m_seq
.end(),
284 [&aName
](const Property
& rProp
) { return rProp
.Name
== aName
; });
285 if (pProp
!= m_seq
.end())
288 throw UnknownPropertyException( aName
);
292 Sequence
< Property
> SAL_CALL
293 XPropertySetInfoImpl2::getProperties()
300 XPropertySetInfoImpl2::hasPropertyByName(
301 const OUString
& aName
)
303 return std::any_of(m_seq
.begin(), m_seq
.end(),
304 [&aName
](const Property
& rProp
) { return rProp
.Name
== aName
; });
308 void FileProvider::initProperties()
310 osl::MutexGuard
aGuard( m_aMutex
);
311 if( m_xPropertySetInfo
.is() )
314 osl_getLocalHostname( &m_HostName
.pData
);
317 m_FileSystemNotation
= FileSystemNotation::UNIX_NOTATION
;
318 #elif defined( _WIN32 )
319 m_FileSystemNotation
= FileSystemNotation::DOS_NOTATION
;
321 m_FileSystemNotation
= FileSystemNotation::UNKNOWN_NOTATION
;
323 osl::Security aSecurity
;
324 aSecurity
.getHomeDir( m_HomeDirectory
);
326 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
327 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
328 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
329 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
331 m_xPropertySetInfo
= new XPropertySetInfoImpl2();
337 Reference
< XPropertySetInfo
> SAL_CALL
338 FileProvider::getPropertySetInfo( )
341 return m_xPropertySetInfo
;
346 FileProvider::setPropertyValue( const OUString
& aPropertyName
,
349 if( !(aPropertyName
== "FileSystemNotation" ||
350 aPropertyName
== "HomeDirectory" ||
351 aPropertyName
== "HostName") )
352 throw UnknownPropertyException( aPropertyName
);
357 FileProvider::getPropertyValue(
358 const OUString
& aPropertyName
)
361 if( aPropertyName
== "FileSystemNotation" )
363 return Any(m_FileSystemNotation
);
365 else if( aPropertyName
== "HomeDirectory" )
367 return Any(m_HomeDirectory
);
369 else if( aPropertyName
== "HostName" )
371 return Any(m_HostName
);
374 throw UnknownPropertyException( aPropertyName
);
379 FileProvider::addPropertyChangeListener(
381 const Reference
< XPropertyChangeListener
>& )
387 FileProvider::removePropertyChangeListener(
389 const Reference
< XPropertyChangeListener
>& )
394 FileProvider::addVetoableChangeListener(
396 const Reference
< XVetoableChangeListener
>& )
402 FileProvider::removeVetoableChangeListener(
404 const Reference
< XVetoableChangeListener
>& )
409 // XFileIdentifierConverter
412 FileProvider::getFileProviderLocality( const OUString
& BaseURL
)
414 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
415 // return -1 (mismatch). What is missing is a fast comparison to ASCII,
417 return BaseURL
.getLength() >= 5
418 && (BaseURL
[0] == 'F' || BaseURL
[0] == 'f')
419 && (BaseURL
[1] == 'I' || BaseURL
[1] == 'i')
420 && (BaseURL
[2] == 'L' || BaseURL
[2] == 'l')
421 && (BaseURL
[3] == 'E' || BaseURL
[3] == 'e')
422 && BaseURL
[4] == ':' ?
426 OUString SAL_CALL
FileProvider::getFileURLFromSystemPath( const OUString
&,
427 const OUString
& SystemPath
)
429 OUString aNormalizedPath
;
430 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath
,aNormalizedPath
) != osl::FileBase::E_None
)
433 return aNormalizedPath
;
436 OUString SAL_CALL
FileProvider::getSystemPathFromFileURL( const OUString
& URL
)
438 OUString aSystemPath
;
439 if (osl::FileBase::getSystemPathFromFileURL( URL
,aSystemPath
) != osl::FileBase::E_None
)
445 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
446 ucb_file_FileProvider_get_implementation(
447 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
449 return cppu::acquire(new FileProvider(context
));
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */