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