LibreOffice Module ucb (master)  1
prov.cxx
Go to the documentation of this file.
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>
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>
30 #include "filglob.hxx"
31 #include "filid.hxx"
32 #include "filtask.hxx"
33 #include "bc.hxx"
34 #include "prov.hxx"
35 
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;
43 
44 #if OSL_DEBUG_LEVEL > 0
45 #define THROW_WHERE SAL_WHERE
46 #else
47 #define THROW_WHERE ""
48 #endif
49 
50 
51 /****************************************************************************/
52 /* */
53 /* */
54 /* FileProvider */
55 /* */
56 /* */
57 /****************************************************************************/
59  : m_xContext(rxContext)
60  , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION)
61 {
62 }
63 
65 {
66 }
67 
68 // XInitialization
70 {
71  if( ! m_pMyShell )
72  m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
73 }
74 
75 
76 void SAL_CALL
78  const Sequence< Any >& aArguments )
79 {
80  if( ! m_pMyShell ) {
81  OUString config;
82  if( aArguments.hasElements() &&
83  (aArguments[0] >>= config) &&
84  config == "NoConfig" )
85  m_pMyShell.reset( new TaskManager( m_xContext, this, false ) );
86  else
87  m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
88  }
89 }
90 
91 // XServiceInfo methods.
92 OUString SAL_CALL
94 {
95  return "com.sun.star.comp.ucb.FileProvider";
96 }
97 
98 sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName )
99 {
100  return cppu::supportsService(this, ServiceName);
101 }
102 
103 Sequence< OUString > SAL_CALL
105 {
106  return { "com.sun.star.ucb.FileContentProvider" };
107 }
108 
109 // XContent
110 
111 
112 Reference< XContent > SAL_CALL
114  const Reference< XContentIdentifier >& xIdentifier )
115 {
116  init();
117  OUString aUnc;
118  bool err = fileaccess::TaskManager::getUnqFromUrl( xIdentifier->getContentIdentifier(),
119  aUnc );
120 
121  if( err )
122  {
123  throw IllegalIdentifierException( THROW_WHERE );
124  }
125 
126  return Reference< XContent >( new BaseContent( m_pMyShell.get(), xIdentifier, aUnc ) );
127 }
128 
129 
130 sal_Int32 SAL_CALL
134 {
135  init();
136  OUString aUrl1 = Id1->getContentIdentifier();
137  OUString aUrl2 = Id2->getContentIdentifier();
138 
139  sal_Int32 iComp = aUrl1.compareTo( aUrl2 );
140 
141  if ( 0 != iComp )
142  {
143  OUString aPath1, aPath2;
144 
147 
148  osl::FileBase::RC error;
149  osl::DirectoryItem aItem1, aItem2;
150 
151  error = osl::DirectoryItem::get( aPath1, aItem1 );
152  if ( error == osl::FileBase::E_None )
153  error = osl::DirectoryItem::get( aPath2, aItem2 );
154 
155  if ( error != osl::FileBase::E_None )
156  return iComp;
157 
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 );
163 
164  if ( error == osl::FileBase::E_None )
165  {
166  iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() );
167 
168 // Quick hack for Windows to threat all file systems as case insensitive
169 #ifdef _WIN32
170  if ( 0 != iComp )
171  {
172  error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 );
173  if ( error == osl::FileBase::E_None )
174  error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 );
175 
176  if ( error == osl::FileBase::E_None )
177  iComp = aPath1.compareToIgnoreAsciiCase( aPath2 );
178  }
179 #endif
180  }
181  }
182 
183  return iComp;
184 }
185 
186 
189  const OUString& ContentId )
190 {
191  init();
192  return new FileContentIdentifier( ContentId,false );
193 }
194 
195 
196 //XPropertySetInfoImpl
197 
198 namespace {
199 
200 class XPropertySetInfoImpl2
201  : public cppu::OWeakObject,
202  public XPropertySetInfo
203 {
204 public:
205  XPropertySetInfoImpl2();
206 
207  // XInterface
208  virtual Any SAL_CALL
209  queryInterface( const Type& aType ) override;
210 
211  virtual void SAL_CALL
212  acquire()
213  noexcept override;
214 
215  virtual void SAL_CALL
216  release()
217  noexcept override;
218 
219 
220  virtual Sequence< Property > SAL_CALL
221  getProperties() override;
222 
223  virtual Property SAL_CALL
224  getPropertyByName( const OUString& aName ) override;
225 
226  virtual sal_Bool SAL_CALL
227  hasPropertyByName( const OUString& Name ) override;
228 
229 
230 private:
231  Sequence< Property > m_seq;
232 };
233 
234 }
235 
236 XPropertySetInfoImpl2::XPropertySetInfoImpl2()
237  : m_seq( 3 )
238 {
239  m_seq[0] = Property( "HostName",
240  -1,
242  PropertyAttribute::READONLY );
243 
244  m_seq[1] = Property( "HomeDirectory",
245  -1,
247  PropertyAttribute::READONLY );
248 
249  m_seq[2] = Property( "FileSystemNotation",
250  -1,
252  PropertyAttribute::READONLY );
253 }
254 
255 void SAL_CALL
256 XPropertySetInfoImpl2::acquire()
257  noexcept
258 {
259  OWeakObject::acquire();
260 }
261 
262 
263 void SAL_CALL
264 XPropertySetInfoImpl2::release()
265  noexcept
266 {
267  OWeakObject::release();
268 }
269 
270 
271 Any SAL_CALL
272 XPropertySetInfoImpl2::queryInterface( const Type& rType )
273 {
274  Any aRet = cppu::queryInterface( rType,
275  static_cast< XPropertySetInfo* >(this) );
276  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
277 }
278 
279 
280 Property SAL_CALL
281 XPropertySetInfoImpl2::getPropertyByName( const OUString& aName )
282 {
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())
286  return *pProp;
287 
288  throw UnknownPropertyException( aName );
289 }
290 
291 
292 Sequence< Property > SAL_CALL
293 XPropertySetInfoImpl2::getProperties()
294 {
295  return m_seq;
296 }
297 
298 
299 sal_Bool SAL_CALL
300 XPropertySetInfoImpl2::hasPropertyByName(
301  const OUString& aName )
302 {
303  return std::any_of(m_seq.begin(), m_seq.end(),
304  [&aName](const Property& rProp) { return rProp.Name == aName; });
305 }
306 
307 
309 {
310  std::scoped_lock aGuard( m_aMutex );
311  if( m_xPropertySetInfo.is() )
312  return;
313 
314  osl_getLocalHostname( &m_HostName.pData );
315 
316 #if defined ( UNX )
317  m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
318 #elif defined( _WIN32 )
319  m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
320 #else
321  m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
322 #endif
323  osl::Security aSecurity;
324  aSecurity.getHomeDir( m_HomeDirectory );
325 
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;
330 
331  m_xPropertySetInfo = new XPropertySetInfoImpl2();
332 }
333 
334 
335 // XPropertySet
336 
339 {
340  initProperties();
341  return m_xPropertySetInfo;
342 }
343 
344 
345 void SAL_CALL
346 FileProvider::setPropertyValue( const OUString& aPropertyName,
347  const Any& )
348 {
349  if( !(aPropertyName == "FileSystemNotation" ||
350  aPropertyName == "HomeDirectory" ||
351  aPropertyName == "HostName") )
352  throw UnknownPropertyException( aPropertyName );
353 }
354 
355 
356 Any SAL_CALL
358  const OUString& aPropertyName )
359 {
360  initProperties();
361  if( aPropertyName == "FileSystemNotation" )
362  {
363  return Any(m_FileSystemNotation);
364  }
365  else if( aPropertyName == "HomeDirectory" )
366  {
367  return Any(m_HomeDirectory);
368  }
369  else if( aPropertyName == "HostName" )
370  {
371  return Any(m_HostName);
372  }
373  else
374  throw UnknownPropertyException( aPropertyName );
375 }
376 
377 
378 void SAL_CALL
380  const OUString&,
382 {
383 }
384 
385 
386 void SAL_CALL
388  const OUString&,
390 {
391 }
392 
393 void SAL_CALL
395  const OUString&,
397 {
398 }
399 
400 
401 void SAL_CALL
403  const OUString&,
405 {
406 }
407 
408 
409 // XFileIdentifierConverter
410 
411 sal_Int32 SAL_CALL
412 FileProvider::getFileProviderLocality( const OUString& BaseURL )
413 {
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,
416  // ignoring case:
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] == ':' ?
423  10 : -1;
424 }
425 
426 OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&,
427  const OUString& SystemPath )
428 {
429  OUString aNormalizedPath;
430  if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
431  return OUString();
432 
433  return aNormalizedPath;
434 }
435 
436 OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL )
437 {
438  OUString aSystemPath;
439  if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
440  return OUString();
441 
442  return aSystemPath;
443 }
444 
445 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
447  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
448 {
449  return cppu::acquire(new FileProvider(context));
450 }
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString SAL_CALL getFileURLFromSystemPath(const OUString &BaseURL, const OUString &SystemPath) override
Definition: prov.cxx:426
Type
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: prov.cxx:357
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:394
FileProvider(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: prov.cxx:58
virtual OUString SAL_CALL getImplementationName() override
Definition: prov.cxx:93
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: prov.cxx:346
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:402
virtual sal_Int32 SAL_CALL getFileProviderLocality(const OUString &BaseURL) override
Definition: prov.cxx:412
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::mutex m_aMutex
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: prov.cxx:104
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: prov.hxx:145
err
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
Definition: prov.cxx:77
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL createContentIdentifier(const OUString &ContentId) override
Definition: prov.cxx:188
virtual sal_Int32 SAL_CALL compareContentIds(const css::uno::Reference< css::ucb::XContentIdentifier > &Id1, const css::uno::Reference< css::ucb::XContentIdentifier > &Id2) override
Definition: prov.cxx:131
unsigned char sal_Bool
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * ucb_file_FileProvider_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: prov.cxx:446
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
Definition: prov.cxx:113
virtual ~FileProvider() override
Definition: prov.cxx:64
std::unique_ptr< TaskManager > m_pMyShell
Definition: prov.hxx:155
#define THROW_WHERE
Definition: prov.cxx:45
static bool getUnqFromUrl(const OUString &Url, OUString &Unq)
Definition: filtask.cxx:1952
tuple config
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: prov.cxx:387
friend class BaseContent
Definition: prov.hxx:54
virtual OUString SAL_CALL getSystemPathFromFileURL(const OUString &URL) override
Definition: prov.cxx:436
Reference< XComponentContext > m_xContext
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: prov.cxx:98
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: prov.cxx:379
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: prov.cxx:338