/src/libreoffice/ucb/source/ucp/file/prov.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
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" |
30 | | #include "filid.hxx" |
31 | | #include "filtask.hxx" |
32 | | #include "bc.hxx" |
33 | | #include "prov.hxx" |
34 | | |
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 | | |
42 | | /****************************************************************************/ |
43 | | /* */ |
44 | | /* */ |
45 | | /* FileProvider */ |
46 | | /* */ |
47 | | /* */ |
48 | | /****************************************************************************/ |
49 | | FileProvider::FileProvider( const Reference< XComponentContext >& rxContext ) |
50 | 11 | : m_xContext(rxContext) |
51 | 11 | , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION) |
52 | 11 | { |
53 | 11 | } |
54 | | |
55 | | FileProvider::~FileProvider() |
56 | 0 | { |
57 | 0 | } |
58 | | |
59 | | // XInitialization |
60 | | void FileProvider::init() |
61 | 284k | { |
62 | 284k | if( ! m_pMyShell ) |
63 | 0 | m_pMyShell.reset( new TaskManager( m_xContext, this, true ) ); |
64 | 284k | } |
65 | | |
66 | | |
67 | | void SAL_CALL |
68 | | FileProvider::initialize( |
69 | | const Sequence< Any >& aArguments ) |
70 | 11 | { |
71 | 11 | if( ! m_pMyShell ) { |
72 | 11 | OUString config; |
73 | 11 | if( aArguments.hasElements() && |
74 | 11 | (aArguments[0] >>= config) && |
75 | 11 | config == "NoConfig" ) |
76 | 11 | m_pMyShell.reset( new TaskManager( m_xContext, this, false ) ); |
77 | 0 | else |
78 | 0 | m_pMyShell.reset( new TaskManager( m_xContext, this, true ) ); |
79 | 11 | } |
80 | 11 | } |
81 | | |
82 | | // XServiceInfo methods. |
83 | | OUString SAL_CALL |
84 | | FileProvider::getImplementationName() |
85 | 0 | { |
86 | 0 | return u"com.sun.star.comp.ucb.FileProvider"_ustr; |
87 | 0 | } |
88 | | |
89 | | sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName ) |
90 | 0 | { |
91 | 0 | return cppu::supportsService(this, ServiceName); |
92 | 0 | } |
93 | | |
94 | | Sequence< OUString > SAL_CALL |
95 | | FileProvider::getSupportedServiceNames() |
96 | 0 | { |
97 | 0 | return { u"com.sun.star.ucb.FileContentProvider"_ustr }; |
98 | 0 | } |
99 | | |
100 | | // XContent |
101 | | |
102 | | Reference< XContent > SAL_CALL |
103 | | FileProvider::queryContent( |
104 | | const Reference< XContentIdentifier >& xIdentifier ) |
105 | 142k | { |
106 | 142k | init(); |
107 | 142k | OUString aUnc; |
108 | 142k | bool err = fileaccess::TaskManager::getUnqFromUrl( xIdentifier->getContentIdentifier(), |
109 | 142k | aUnc ); |
110 | | |
111 | 142k | if( err ) |
112 | 0 | { |
113 | 0 | throw IllegalIdentifierException(); |
114 | 0 | } |
115 | | |
116 | 142k | return Reference<XContent>(new BaseContent(m_pMyShell.get(), xIdentifier, aUnc)); |
117 | 142k | } |
118 | | |
119 | | sal_Int32 SAL_CALL |
120 | | FileProvider::compareContentIds( |
121 | | const Reference< XContentIdentifier >& Id1, |
122 | | const Reference< XContentIdentifier >& Id2 ) |
123 | 0 | { |
124 | 0 | init(); |
125 | 0 | OUString aUrl1 = Id1->getContentIdentifier(); |
126 | 0 | OUString aUrl2 = Id2->getContentIdentifier(); |
127 | |
|
128 | 0 | sal_Int32 iComp = aUrl1.compareTo( aUrl2 ); |
129 | |
|
130 | 0 | if ( 0 != iComp ) |
131 | 0 | { |
132 | 0 | OUString aPath1, aPath2; |
133 | |
|
134 | 0 | fileaccess::TaskManager::getUnqFromUrl( aUrl1, aPath1 ); |
135 | 0 | fileaccess::TaskManager::getUnqFromUrl( aUrl2, aPath2 ); |
136 | |
|
137 | 0 | osl::FileBase::RC error; |
138 | 0 | osl::DirectoryItem aItem1, aItem2; |
139 | |
|
140 | 0 | error = osl::DirectoryItem::get( aPath1, aItem1 ); |
141 | 0 | if ( error == osl::FileBase::E_None ) |
142 | 0 | error = osl::DirectoryItem::get( aPath2, aItem2 ); |
143 | |
|
144 | 0 | if ( error != osl::FileBase::E_None ) |
145 | 0 | return iComp; |
146 | | |
147 | 0 | osl::FileStatus aStatus1( osl_FileStatus_Mask_FileURL ); |
148 | 0 | osl::FileStatus aStatus2( osl_FileStatus_Mask_FileURL ); |
149 | 0 | error = aItem1.getFileStatus( aStatus1 ); |
150 | 0 | if ( error == osl::FileBase::E_None ) |
151 | 0 | error = aItem2.getFileStatus( aStatus2 ); |
152 | |
|
153 | 0 | if ( error == osl::FileBase::E_None ) |
154 | 0 | { |
155 | 0 | iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() ); |
156 | | |
157 | | // Quick hack for Windows to treat all file systems as case insensitive |
158 | | #ifdef _WIN32 |
159 | | if ( 0 != iComp ) |
160 | | { |
161 | | error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 ); |
162 | | if ( error == osl::FileBase::E_None ) |
163 | | error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 ); |
164 | | |
165 | | if ( error == osl::FileBase::E_None ) |
166 | | iComp = aPath1.compareToIgnoreAsciiCase( aPath2 ); |
167 | | } |
168 | | #endif |
169 | 0 | } |
170 | 0 | } |
171 | | |
172 | 0 | return iComp; |
173 | 0 | } |
174 | | |
175 | | |
176 | | Reference< XContentIdentifier > SAL_CALL |
177 | | FileProvider::createContentIdentifier( |
178 | | const OUString& ContentId ) |
179 | 142k | { |
180 | 142k | init(); |
181 | 142k | return new FileContentIdentifier( ContentId,false ); |
182 | 142k | } |
183 | | |
184 | | |
185 | | //XPropertySetInfoImpl |
186 | | |
187 | | namespace fileaccess { |
188 | | |
189 | | class XPropertySetInfoImpl2 |
190 | | : public cppu::OWeakObject, |
191 | | public XPropertySetInfo |
192 | | { |
193 | | public: |
194 | | XPropertySetInfoImpl2(); |
195 | | |
196 | | // XInterface |
197 | | virtual Any SAL_CALL |
198 | | queryInterface( const Type& aType ) override; |
199 | | |
200 | | virtual void SAL_CALL |
201 | | acquire() |
202 | | noexcept override; |
203 | | |
204 | | virtual void SAL_CALL |
205 | | release() |
206 | | noexcept override; |
207 | | |
208 | | |
209 | | virtual Sequence< Property > SAL_CALL |
210 | | getProperties() override; |
211 | | |
212 | | virtual Property SAL_CALL |
213 | | getPropertyByName( const OUString& aName ) override; |
214 | | |
215 | | virtual sal_Bool SAL_CALL |
216 | | hasPropertyByName( const OUString& Name ) override; |
217 | | |
218 | | |
219 | | private: |
220 | | Sequence< Property > m_seq; |
221 | | }; |
222 | | |
223 | | } |
224 | | |
225 | | XPropertySetInfoImpl2::XPropertySetInfoImpl2() |
226 | 0 | : m_seq{ Property( u"HostName"_ustr, |
227 | 0 | -1, |
228 | 0 | cppu::UnoType<OUString>::get(), |
229 | 0 | PropertyAttribute::READONLY ), |
230 | 0 | Property( u"HomeDirectory"_ustr, |
231 | 0 | -1, |
232 | 0 | cppu::UnoType<OUString>::get(), |
233 | 0 | PropertyAttribute::READONLY ), |
234 | 0 | Property( u"FileSystemNotation"_ustr, |
235 | 0 | -1, |
236 | 0 | cppu::UnoType<sal_Int32>::get(), |
237 | 0 | PropertyAttribute::READONLY )} |
238 | 0 | { |
239 | 0 | } |
240 | | |
241 | | void SAL_CALL |
242 | | XPropertySetInfoImpl2::acquire() |
243 | | noexcept |
244 | 0 | { |
245 | 0 | OWeakObject::acquire(); |
246 | 0 | } |
247 | | |
248 | | |
249 | | void SAL_CALL |
250 | | XPropertySetInfoImpl2::release() |
251 | | noexcept |
252 | 0 | { |
253 | 0 | OWeakObject::release(); |
254 | 0 | } |
255 | | |
256 | | |
257 | | Any SAL_CALL |
258 | | XPropertySetInfoImpl2::queryInterface( const Type& rType ) |
259 | 0 | { |
260 | 0 | Any aRet = cppu::queryInterface( rType, |
261 | 0 | static_cast< XPropertySetInfo* >(this) ); |
262 | 0 | return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); |
263 | 0 | } |
264 | | |
265 | | |
266 | | Property SAL_CALL |
267 | | XPropertySetInfoImpl2::getPropertyByName( const OUString& aName ) |
268 | 0 | { |
269 | 0 | auto pProp = std::find_if(std::cbegin(m_seq), std::cend(m_seq), |
270 | 0 | [&aName](const Property& rProp) { return rProp.Name == aName; }); |
271 | 0 | if (pProp != std::cend(m_seq)) |
272 | 0 | return *pProp; |
273 | | |
274 | 0 | throw UnknownPropertyException( aName ); |
275 | 0 | } |
276 | | |
277 | | |
278 | | Sequence< Property > SAL_CALL |
279 | | XPropertySetInfoImpl2::getProperties() |
280 | 0 | { |
281 | 0 | return m_seq; |
282 | 0 | } |
283 | | |
284 | | |
285 | | sal_Bool SAL_CALL |
286 | | XPropertySetInfoImpl2::hasPropertyByName( |
287 | | const OUString& aName ) |
288 | 0 | { |
289 | 0 | return std::any_of(std::cbegin(m_seq), std::cend(m_seq), |
290 | 0 | [&aName](const Property& rProp) { return rProp.Name == aName; }); |
291 | 0 | } |
292 | | |
293 | | |
294 | | void FileProvider::initProperties(std::unique_lock<std::mutex>& /*rGuard*/) |
295 | 0 | { |
296 | 0 | if( m_xPropertySetInfo.is() ) |
297 | 0 | return; |
298 | | |
299 | 0 | osl_getLocalHostname( &m_HostName.pData ); |
300 | |
|
301 | 0 | #if defined ( UNX ) |
302 | 0 | m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION; |
303 | | #elif defined( _WIN32 ) |
304 | | m_FileSystemNotation = FileSystemNotation::DOS_NOTATION; |
305 | | #else |
306 | | m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION; |
307 | | #endif |
308 | 0 | osl::Security aSecurity; |
309 | 0 | aSecurity.getHomeDir( m_HomeDirectory ); |
310 | | |
311 | | // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0; |
312 | | // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1; |
313 | | // static const sal_Int32 DOS_NOTATION = (sal_Int32)2; |
314 | | // static const sal_Int32 MAC_NOTATION = (sal_Int32)3; |
315 | |
|
316 | 0 | m_xPropertySetInfo = new XPropertySetInfoImpl2(); |
317 | 0 | } |
318 | | |
319 | | |
320 | | // XPropertySet |
321 | | |
322 | | Reference< XPropertySetInfo > SAL_CALL |
323 | | FileProvider::getPropertySetInfo( ) |
324 | 0 | { |
325 | 0 | std::unique_lock aGuard( m_aMutex ); |
326 | 0 | initProperties(aGuard); |
327 | 0 | return m_xPropertySetInfo; |
328 | 0 | } |
329 | | |
330 | | |
331 | | void SAL_CALL |
332 | | FileProvider::setPropertyValue( const OUString& aPropertyName, |
333 | | const Any& ) |
334 | 0 | { |
335 | 0 | if( !(aPropertyName == "FileSystemNotation" || |
336 | 0 | aPropertyName == "HomeDirectory" || |
337 | 0 | aPropertyName == "HostName") ) |
338 | 0 | throw UnknownPropertyException( aPropertyName ); |
339 | 0 | } |
340 | | |
341 | | |
342 | | Any SAL_CALL |
343 | | FileProvider::getPropertyValue( |
344 | | const OUString& aPropertyName ) |
345 | 0 | { |
346 | 0 | std::unique_lock aGuard( m_aMutex ); |
347 | 0 | initProperties(aGuard); |
348 | 0 | if( aPropertyName == "FileSystemNotation" ) |
349 | 0 | { |
350 | 0 | return Any(m_FileSystemNotation); |
351 | 0 | } |
352 | 0 | else if( aPropertyName == "HomeDirectory" ) |
353 | 0 | { |
354 | 0 | return Any(m_HomeDirectory); |
355 | 0 | } |
356 | 0 | else if( aPropertyName == "HostName" ) |
357 | 0 | { |
358 | 0 | return Any(m_HostName); |
359 | 0 | } |
360 | 0 | else |
361 | 0 | throw UnknownPropertyException( aPropertyName ); |
362 | 0 | } |
363 | | |
364 | | |
365 | | void SAL_CALL |
366 | | FileProvider::addPropertyChangeListener( |
367 | | const OUString&, |
368 | | const Reference< XPropertyChangeListener >& ) |
369 | 0 | { |
370 | 0 | } |
371 | | |
372 | | |
373 | | void SAL_CALL |
374 | | FileProvider::removePropertyChangeListener( |
375 | | const OUString&, |
376 | | const Reference< XPropertyChangeListener >& ) |
377 | 0 | { |
378 | 0 | } |
379 | | |
380 | | void SAL_CALL |
381 | | FileProvider::addVetoableChangeListener( |
382 | | const OUString&, |
383 | | const Reference< XVetoableChangeListener >& ) |
384 | 0 | { |
385 | 0 | } |
386 | | |
387 | | |
388 | | void SAL_CALL |
389 | | FileProvider::removeVetoableChangeListener( |
390 | | const OUString&, |
391 | | const Reference< XVetoableChangeListener >& ) |
392 | 0 | { |
393 | 0 | } |
394 | | |
395 | | |
396 | | // XFileIdentifierConverter |
397 | | |
398 | | sal_Int32 SAL_CALL |
399 | | FileProvider::getFileProviderLocality( const OUString& BaseURL ) |
400 | 0 | { |
401 | | // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise |
402 | | // return -1 (mismatch). What is missing is a fast comparison to ASCII, |
403 | | // ignoring case: |
404 | 0 | return BaseURL.getLength() >= 5 |
405 | 0 | && (BaseURL[0] == 'F' || BaseURL[0] == 'f') |
406 | 0 | && (BaseURL[1] == 'I' || BaseURL[1] == 'i') |
407 | 0 | && (BaseURL[2] == 'L' || BaseURL[2] == 'l') |
408 | 0 | && (BaseURL[3] == 'E' || BaseURL[3] == 'e') |
409 | 0 | && BaseURL[4] == ':' ? |
410 | 0 | 10 : -1; |
411 | 0 | } |
412 | | |
413 | | OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&, |
414 | | const OUString& SystemPath ) |
415 | 0 | { |
416 | 0 | OUString aNormalizedPath; |
417 | 0 | if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None ) |
418 | 0 | return OUString(); |
419 | | |
420 | 0 | return aNormalizedPath; |
421 | 0 | } |
422 | | |
423 | | OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL ) |
424 | 0 | { |
425 | 0 | OUString aSystemPath; |
426 | 0 | if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None ) |
427 | 0 | return OUString(); |
428 | | |
429 | 0 | return aSystemPath; |
430 | 0 | } |
431 | | |
432 | | extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* |
433 | | ucb_file_FileProvider_get_implementation( |
434 | | css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) |
435 | 11 | { |
436 | 11 | return cppu::acquire(new FileProvider(context)); |
437 | 11 | } |
438 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |