Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / ucp / file / prov.cxx
blob9a7052e173049dcc649279ae8f9edb6dac306b09
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
31 #include "filid.hxx"
32 #include "filtask.hxx"
33 #include "bc.hxx"
34 #include "prov.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
46 #else
47 #define THROW_WHERE ""
48 #endif
51 extern "C" SAL_DLLPUBLIC_EXPORT void * ucpfile_component_getFactory(
52 const sal_Char * pImplName, void * pServiceManager, void * )
54 void * pRet = nullptr;
56 Reference< XMultiServiceFactory > xSMgr(
57 static_cast< XMultiServiceFactory * >( pServiceManager ) );
58 Reference< XSingleServiceFactory > xFactory;
61 // File Content Provider.
64 if ( fileaccess::TaskManager::getImplementationName_static().
65 equalsAscii( pImplName ) )
67 xFactory = FileProvider::createServiceFactory( xSMgr );
71 if ( xFactory.is() )
73 xFactory->acquire();
74 pRet = xFactory.get();
77 return pRet;
80 /****************************************************************************/
81 /* */
82 /* */
83 /* FileProvider */
84 /* */
85 /* */
86 /****************************************************************************/
87 FileProvider::FileProvider( const Reference< XComponentContext >& rxContext )
88 : m_xContext(rxContext)
89 , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION)
93 FileProvider::~FileProvider()
97 // XInitialization
98 void FileProvider::init()
100 if( ! m_pMyShell )
101 m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
105 void SAL_CALL
106 FileProvider::initialize(
107 const Sequence< Any >& aArguments )
109 if( ! m_pMyShell ) {
110 OUString config;
111 if( aArguments.hasElements() &&
112 (aArguments[0] >>= config) &&
113 config == "NoConfig" )
114 m_pMyShell.reset( new TaskManager( m_xContext, this, false ) );
115 else
116 m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
120 // XServiceInfo methods.
121 OUString SAL_CALL
122 FileProvider::getImplementationName()
124 return fileaccess::TaskManager::getImplementationName_static();
127 sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName )
129 return cppu::supportsService(this, ServiceName);
132 Sequence< OUString > SAL_CALL
133 FileProvider::getSupportedServiceNames()
135 return fileaccess::TaskManager::getSupportedServiceNames_static();
138 Reference< XSingleServiceFactory >
139 FileProvider::createServiceFactory(
140 const Reference< XMultiServiceFactory >& rxServiceMgr )
142 return cppu::createSingleFactory(
143 rxServiceMgr,
144 fileaccess::TaskManager::getImplementationName_static(),
145 FileProvider::CreateInstance,
146 fileaccess::TaskManager::getSupportedServiceNames_static() );
149 Reference< XInterface > SAL_CALL
150 FileProvider::CreateInstance(
151 const Reference< XMultiServiceFactory >& xMultiServiceFactory )
153 XServiceInfo* xP = new FileProvider(comphelper::getComponentContext(xMultiServiceFactory));
154 return Reference< XInterface >::query( xP );
158 // XContent
161 Reference< XContent > SAL_CALL
162 FileProvider::queryContent(
163 const Reference< XContentIdentifier >& xIdentifier )
165 init();
166 OUString aUnc;
167 bool err = fileaccess::TaskManager::getUnqFromUrl( xIdentifier->getContentIdentifier(),
168 aUnc );
170 if( err )
171 throw IllegalIdentifierException( THROW_WHERE );
173 return Reference< XContent >( new BaseContent( m_pMyShell.get(), xIdentifier, aUnc ) );
177 sal_Int32 SAL_CALL
178 FileProvider::compareContentIds(
179 const Reference< XContentIdentifier >& Id1,
180 const Reference< XContentIdentifier >& Id2 )
182 init();
183 OUString aUrl1 = Id1->getContentIdentifier();
184 OUString aUrl2 = Id2->getContentIdentifier();
186 sal_Int32 iComp = aUrl1.compareTo( aUrl2 );
188 if ( 0 != iComp )
190 OUString aPath1, aPath2;
192 fileaccess::TaskManager::getUnqFromUrl( aUrl1, aPath1 );
193 fileaccess::TaskManager::getUnqFromUrl( aUrl2, aPath2 );
195 osl::FileBase::RC error;
196 osl::DirectoryItem aItem1, aItem2;
198 error = osl::DirectoryItem::get( aPath1, aItem1 );
199 if ( error == osl::FileBase::E_None )
200 error = osl::DirectoryItem::get( aPath2, aItem2 );
202 if ( error != osl::FileBase::E_None )
203 return iComp;
205 osl::FileStatus aStatus1( osl_FileStatus_Mask_FileURL );
206 osl::FileStatus aStatus2( osl_FileStatus_Mask_FileURL );
207 error = aItem1.getFileStatus( aStatus1 );
208 if ( error == osl::FileBase::E_None )
209 error = aItem2.getFileStatus( aStatus2 );
211 if ( error == osl::FileBase::E_None )
213 iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() );
215 // Quick hack for Windows to threat all file systems as case insensitive
216 #ifdef _WIN32
217 if ( 0 != iComp )
219 error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 );
220 if ( error == osl::FileBase::E_None )
221 error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 );
223 if ( error == osl::FileBase::E_None )
224 iComp = aPath1.compareToIgnoreAsciiCase( aPath2 );
226 #endif
230 return iComp;
234 Reference< XContentIdentifier > SAL_CALL
235 FileProvider::createContentIdentifier(
236 const OUString& ContentId )
238 init();
239 FileContentIdentifier* p = new FileContentIdentifier( ContentId,false );
240 return Reference< XContentIdentifier >( p );
244 //XPropertySetInfoImpl
246 class XPropertySetInfoImpl2
247 : public cppu::OWeakObject,
248 public XPropertySetInfo
250 public:
251 XPropertySetInfoImpl2();
253 // XInterface
254 virtual Any SAL_CALL
255 queryInterface( const Type& aType ) override;
257 virtual void SAL_CALL
258 acquire()
259 throw() override;
261 virtual void SAL_CALL
262 release()
263 throw() override;
266 virtual Sequence< Property > SAL_CALL
267 getProperties() override;
269 virtual Property SAL_CALL
270 getPropertyByName( const OUString& aName ) override;
272 virtual sal_Bool SAL_CALL
273 hasPropertyByName( const OUString& Name ) override;
276 private:
277 Sequence< Property > m_seq;
281 XPropertySetInfoImpl2::XPropertySetInfoImpl2()
282 : m_seq( 3 )
284 m_seq[0] = Property( "HostName",
286 cppu::UnoType<OUString>::get(),
287 PropertyAttribute::READONLY );
289 m_seq[1] = Property( "HomeDirectory",
291 cppu::UnoType<OUString>::get(),
292 PropertyAttribute::READONLY );
294 m_seq[2] = Property( "FileSystemNotation",
296 cppu::UnoType<sal_Int32>::get(),
297 PropertyAttribute::READONLY );
300 void SAL_CALL
301 XPropertySetInfoImpl2::acquire()
302 throw()
304 OWeakObject::acquire();
308 void SAL_CALL
309 XPropertySetInfoImpl2::release()
310 throw()
312 OWeakObject::release();
316 Any SAL_CALL
317 XPropertySetInfoImpl2::queryInterface( const Type& rType )
319 Any aRet = cppu::queryInterface( rType,
320 static_cast< XPropertySetInfo* >(this) );
321 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
325 Property SAL_CALL
326 XPropertySetInfoImpl2::getPropertyByName( const OUString& aName )
328 auto pProp = std::find_if(m_seq.begin(), m_seq.end(),
329 [&aName](const Property& rProp) { return rProp.Name == aName; });
330 if (pProp != m_seq.end())
331 return *pProp;
333 throw UnknownPropertyException( aName );
337 Sequence< Property > SAL_CALL
338 XPropertySetInfoImpl2::getProperties()
340 return m_seq;
344 sal_Bool SAL_CALL
345 XPropertySetInfoImpl2::hasPropertyByName(
346 const OUString& aName )
348 return std::any_of(m_seq.begin(), m_seq.end(),
349 [&aName](const Property& rProp) { return rProp.Name == aName; });
353 void FileProvider::initProperties()
355 osl::MutexGuard aGuard( m_aMutex );
356 if( ! m_xPropertySetInfo.is() )
358 osl_getLocalHostname( &m_HostName.pData );
360 #if defined ( UNX )
361 m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
362 #elif defined( WNT )
363 m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
364 #else
365 m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
366 #endif
367 osl::Security aSecurity;
368 aSecurity.getHomeDir( m_HomeDirectory );
370 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
371 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
372 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
373 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
375 XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2();
376 m_xPropertySetInfo.set( p );
381 // XPropertySet
383 Reference< XPropertySetInfo > SAL_CALL
384 FileProvider::getPropertySetInfo( )
386 initProperties();
387 return m_xPropertySetInfo;
391 void SAL_CALL
392 FileProvider::setPropertyValue( const OUString& aPropertyName,
393 const Any& )
395 if( !(aPropertyName == "FileSystemNotation" ||
396 aPropertyName == "HomeDirectory" ||
397 aPropertyName == "HostName") )
398 throw UnknownPropertyException( aPropertyName );
402 Any SAL_CALL
403 FileProvider::getPropertyValue(
404 const OUString& aPropertyName )
406 initProperties();
407 if( aPropertyName == "FileSystemNotation" )
409 return Any(m_FileSystemNotation);
411 else if( aPropertyName == "HomeDirectory" )
413 return Any(m_HomeDirectory);
415 else if( aPropertyName == "HostName" )
417 return Any(m_HostName);
419 else
420 throw UnknownPropertyException( aPropertyName );
424 void SAL_CALL
425 FileProvider::addPropertyChangeListener(
426 const OUString&,
427 const Reference< XPropertyChangeListener >& )
432 void SAL_CALL
433 FileProvider::removePropertyChangeListener(
434 const OUString&,
435 const Reference< XPropertyChangeListener >& )
439 void SAL_CALL
440 FileProvider::addVetoableChangeListener(
441 const OUString&,
442 const Reference< XVetoableChangeListener >& )
447 void SAL_CALL
448 FileProvider::removeVetoableChangeListener(
449 const OUString&,
450 const Reference< XVetoableChangeListener >& )
455 // XFileIdentifierConverter
457 sal_Int32 SAL_CALL
458 FileProvider::getFileProviderLocality( const OUString& BaseURL )
460 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
461 // return -1 (mismatch). What is missing is a fast comparison to ASCII,
462 // ignoring case:
463 return BaseURL.getLength() >= 5
464 && (BaseURL[0] == 'F' || BaseURL[0] == 'f')
465 && (BaseURL[1] == 'I' || BaseURL[1] == 'i')
466 && (BaseURL[2] == 'L' || BaseURL[2] == 'l')
467 && (BaseURL[3] == 'E' || BaseURL[3] == 'e')
468 && BaseURL[4] == ':' ?
469 10 : -1;
472 OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&,
473 const OUString& SystemPath )
475 OUString aNormalizedPath;
476 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
477 return OUString();
479 return aNormalizedPath;
482 OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL )
484 OUString aSystemPath;
485 if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
486 return OUString();
488 return aSystemPath;
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */