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{ Property( "HostName",
238  -1,
240  PropertyAttribute::READONLY ),
241  Property( "HomeDirectory",
242  -1,
244  PropertyAttribute::READONLY ),
245  Property( "FileSystemNotation",
246  -1,
248  PropertyAttribute::READONLY )}
249 {
250 }
251 
252 void SAL_CALL
253 XPropertySetInfoImpl2::acquire()
254  noexcept
255 {
256  OWeakObject::acquire();
257 }
258 
259 
260 void SAL_CALL
261 XPropertySetInfoImpl2::release()
262  noexcept
263 {
264  OWeakObject::release();
265 }
266 
267 
268 Any SAL_CALL
269 XPropertySetInfoImpl2::queryInterface( const Type& rType )
270 {
271  Any aRet = cppu::queryInterface( rType,
272  static_cast< XPropertySetInfo* >(this) );
273  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
274 }
275 
276 
277 Property SAL_CALL
278 XPropertySetInfoImpl2::getPropertyByName( const OUString& aName )
279 {
280  auto pProp = std::find_if(std::cbegin(m_seq), std::cend(m_seq),
281  [&aName](const Property& rProp) { return rProp.Name == aName; });
282  if (pProp != std::cend(m_seq))
283  return *pProp;
284 
285  throw UnknownPropertyException( aName );
286 }
287 
288 
289 Sequence< Property > SAL_CALL
290 XPropertySetInfoImpl2::getProperties()
291 {
292  return m_seq;
293 }
294 
295 
296 sal_Bool SAL_CALL
297 XPropertySetInfoImpl2::hasPropertyByName(
298  const OUString& aName )
299 {
300  return std::any_of(std::cbegin(m_seq), std::cend(m_seq),
301  [&aName](const Property& rProp) { return rProp.Name == aName; });
302 }
303 
304 
306 {
307  std::scoped_lock aGuard( m_aMutex );
308  if( m_xPropertySetInfo.is() )
309  return;
310 
311  osl_getLocalHostname( &m_HostName.pData );
312 
313 #if defined ( UNX )
314  m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
315 #elif defined( _WIN32 )
316  m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
317 #else
318  m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
319 #endif
320  osl::Security aSecurity;
321  aSecurity.getHomeDir( m_HomeDirectory );
322 
323  // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
324  // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
325  // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
326  // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
327 
328  m_xPropertySetInfo = new XPropertySetInfoImpl2();
329 }
330 
331 
332 // XPropertySet
333 
336 {
337  initProperties();
338  return m_xPropertySetInfo;
339 }
340 
341 
342 void SAL_CALL
343 FileProvider::setPropertyValue( const OUString& aPropertyName,
344  const Any& )
345 {
346  if( !(aPropertyName == "FileSystemNotation" ||
347  aPropertyName == "HomeDirectory" ||
348  aPropertyName == "HostName") )
349  throw UnknownPropertyException( aPropertyName );
350 }
351 
352 
353 Any SAL_CALL
355  const OUString& aPropertyName )
356 {
357  initProperties();
358  if( aPropertyName == "FileSystemNotation" )
359  {
360  return Any(m_FileSystemNotation);
361  }
362  else if( aPropertyName == "HomeDirectory" )
363  {
364  return Any(m_HomeDirectory);
365  }
366  else if( aPropertyName == "HostName" )
367  {
368  return Any(m_HostName);
369  }
370  else
371  throw UnknownPropertyException( aPropertyName );
372 }
373 
374 
375 void SAL_CALL
377  const OUString&,
379 {
380 }
381 
382 
383 void SAL_CALL
385  const OUString&,
387 {
388 }
389 
390 void SAL_CALL
392  const OUString&,
394 {
395 }
396 
397 
398 void SAL_CALL
400  const OUString&,
402 {
403 }
404 
405 
406 // XFileIdentifierConverter
407 
408 sal_Int32 SAL_CALL
409 FileProvider::getFileProviderLocality( const OUString& BaseURL )
410 {
411  // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
412  // return -1 (mismatch). What is missing is a fast comparison to ASCII,
413  // ignoring case:
414  return BaseURL.getLength() >= 5
415  && (BaseURL[0] == 'F' || BaseURL[0] == 'f')
416  && (BaseURL[1] == 'I' || BaseURL[1] == 'i')
417  && (BaseURL[2] == 'L' || BaseURL[2] == 'l')
418  && (BaseURL[3] == 'E' || BaseURL[3] == 'e')
419  && BaseURL[4] == ':' ?
420  10 : -1;
421 }
422 
423 OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&,
424  const OUString& SystemPath )
425 {
426  OUString aNormalizedPath;
427  if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
428  return OUString();
429 
430  return aNormalizedPath;
431 }
432 
433 OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL )
434 {
435  OUString aSystemPath;
436  if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
437  return OUString();
438 
439  return aSystemPath;
440 }
441 
442 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
444  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
445 {
446  return cppu::acquire(new FileProvider(context));
447 }
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString SAL_CALL getFileURLFromSystemPath(const OUString &BaseURL, const OUString &SystemPath) override
Definition: prov.cxx:423
Type
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: prov.cxx:354
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:391
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:343
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:399
virtual sal_Int32 SAL_CALL getFileProviderLocality(const OUString &BaseURL) override
Definition: prov.cxx:409
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:443
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:1953
tuple config
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: prov.cxx:384
friend class BaseContent
Definition: prov.hxx:54
virtual OUString SAL_CALL getSystemPathFromFileURL(const OUString &URL) override
Definition: prov.cxx:433
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:376
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:335