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>
23 #include <sal/log.hxx>
24 #include <tools/urlobj.hxx>
25 #include <ucbhelper/content.hxx>
28 #include <com/sun/star/beans/PropertyAttribute.hpp>
29 #include <com/sun/star/ucb/FileSystemNotation.hpp>
30 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
31 #include <com/sun/star/beans/PropertyState.hpp>
32 #include <cppuhelper/factory.hxx>
34 #include "filglob.hxx"
35 #include "filid.hxx"
36 #include "filtask.hxx"
37 #include "bc.hxx"
38 #include "prov.hxx"
39 
40 using namespace fileaccess;
41 using namespace com::sun::star;
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::lang;
44 using namespace com::sun::star::beans;
45 using namespace com::sun::star::ucb;
46 using namespace com::sun::star::container;
47 
48 #if OSL_DEBUG_LEVEL > 0
49 #define THROW_WHERE SAL_WHERE
50 #else
51 #define THROW_WHERE ""
52 #endif
53 
54 
55 extern "C" SAL_DLLPUBLIC_EXPORT void * ucpfile_component_getFactory(
56  const sal_Char * pImplName, void * pServiceManager, void * )
57 {
58  void * pRet = nullptr;
59 
61  static_cast< XMultiServiceFactory * >( pServiceManager ) );
63 
64 
65  // File Content Provider.
66 
67 
69  equalsAscii( pImplName ) )
70  {
71  xFactory = FileProvider::createServiceFactory( xSMgr );
72  }
73 
74 
75  if ( xFactory.is() )
76  {
77  xFactory->acquire();
78  pRet = xFactory.get();
79  }
80 
81  return pRet;
82 }
83 
84 /****************************************************************************/
85 /* */
86 /* */
87 /* FileProvider */
88 /* */
89 /* */
90 /****************************************************************************/
92  : m_xContext(rxContext)
93  , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION)
94 {
95 }
96 
98 {
99 }
100 
101 // XInitialization
103 {
104  if( ! m_pMyShell )
105  m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
106 }
107 
108 
109 void SAL_CALL
111  const Sequence< Any >& aArguments )
112 {
113  if( ! m_pMyShell ) {
114  OUString config;
115  if( aArguments.hasElements() &&
116  (aArguments[0] >>= config) &&
117  config == "NoConfig" )
118  m_pMyShell.reset( new TaskManager( m_xContext, this, false ) );
119  else
120  m_pMyShell.reset( new TaskManager( m_xContext, this, true ) );
121  }
122 }
123 
124 // XServiceInfo methods.
125 OUString SAL_CALL
127 {
129 }
130 
131 sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName )
132 {
133  return cppu::supportsService(this, ServiceName);
134 }
135 
136 Sequence< OUString > SAL_CALL
138 {
140 }
141 
144  const Reference< XMultiServiceFactory >& rxServiceMgr )
145 {
147  rxServiceMgr,
151 }
152 
155  const Reference< XMultiServiceFactory >& xMultiServiceFactory )
156 {
157  XServiceInfo* xP = new FileProvider(comphelper::getComponentContext(xMultiServiceFactory));
158  return Reference< XInterface >::query( xP );
159 }
160 
161 
162 // XContent
163 
164 
165 Reference< XContent > SAL_CALL
167  const Reference< XContentIdentifier >& xIdentifier )
168 {
169  init();
170  OUString aUnc;
171  bool err = fileaccess::TaskManager::getUnqFromUrl( xIdentifier->getContentIdentifier(),
172  aUnc );
173 
174  if( err )
175  {
176  // Hack to retry file://<host>/... URLs as smb URLs:
177  INetURLObject url(xIdentifier->getContentIdentifier());
178  if (url.GetProtocol() == INetProtocol::File
179  && !url.GetHost(INetURLObject::DecodeMechanism::NONE).isEmpty())
180  {
181  url.changeScheme(INetProtocol::Smb);
182  ucbhelper::Content content;
184  url.GetMainURL(INetURLObject::DecodeMechanism::NONE),
185  css::uno::Reference<css::ucb::XCommandEnvironment>(), m_xContext, content))
186  {
187  return content.get();
188  }
189  }
190 
191  throw IllegalIdentifierException( THROW_WHERE );
192  }
193 
194  return Reference< XContent >( new BaseContent( m_pMyShell.get(), xIdentifier, aUnc ) );
195 }
196 
197 
198 sal_Int32 SAL_CALL
202 {
203  init();
204  OUString aUrl1 = Id1->getContentIdentifier();
205  OUString aUrl2 = Id2->getContentIdentifier();
206 
207  sal_Int32 iComp = aUrl1.compareTo( aUrl2 );
208 
209  if ( 0 != iComp )
210  {
211  OUString aPath1, aPath2;
212 
215 
216  osl::FileBase::RC error;
217  osl::DirectoryItem aItem1, aItem2;
218 
219  error = osl::DirectoryItem::get( aPath1, aItem1 );
220  if ( error == osl::FileBase::E_None )
221  error = osl::DirectoryItem::get( aPath2, aItem2 );
222 
223  if ( error != osl::FileBase::E_None )
224  return iComp;
225 
226  osl::FileStatus aStatus1( osl_FileStatus_Mask_FileURL );
227  osl::FileStatus aStatus2( osl_FileStatus_Mask_FileURL );
228  error = aItem1.getFileStatus( aStatus1 );
229  if ( error == osl::FileBase::E_None )
230  error = aItem2.getFileStatus( aStatus2 );
231 
232  if ( error == osl::FileBase::E_None )
233  {
234  iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() );
235 
236 // Quick hack for Windows to threat all file systems as case insensitive
237 #ifdef _WIN32
238  if ( 0 != iComp )
239  {
240  error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 );
241  if ( error == osl::FileBase::E_None )
242  error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 );
243 
244  if ( error == osl::FileBase::E_None )
245  iComp = aPath1.compareToIgnoreAsciiCase( aPath2 );
246  }
247 #endif
248  }
249  }
250 
251  return iComp;
252 }
253 
254 
257  const OUString& ContentId )
258 {
259  init();
260  FileContentIdentifier* p = new FileContentIdentifier( ContentId,false );
262 }
263 
264 
265 //XPropertySetInfoImpl
266 
268  : public cppu::OWeakObject,
269  public XPropertySetInfo
270 {
271 public:
273 
274  // XInterface
275  virtual Any SAL_CALL
276  queryInterface( const Type& aType ) override;
277 
278  virtual void SAL_CALL
279  acquire()
280  throw() override;
281 
282  virtual void SAL_CALL
283  release()
284  throw() override;
285 
286 
287  virtual Sequence< Property > SAL_CALL
288  getProperties() override;
289 
290  virtual Property SAL_CALL
291  getPropertyByName( const OUString& aName ) override;
292 
293  virtual sal_Bool SAL_CALL
294  hasPropertyByName( const OUString& Name ) override;
295 
296 
297 private:
299 };
300 
301 
303  : m_seq( 3 )
304 {
305  m_seq[0] = Property( "HostName",
306  -1,
308  PropertyAttribute::READONLY );
309 
310  m_seq[1] = Property( "HomeDirectory",
311  -1,
313  PropertyAttribute::READONLY );
314 
315  m_seq[2] = Property( "FileSystemNotation",
316  -1,
318  PropertyAttribute::READONLY );
319 }
320 
321 void SAL_CALL
323  throw()
324 {
325  OWeakObject::acquire();
326 }
327 
328 
329 void SAL_CALL
331  throw()
332 {
333  OWeakObject::release();
334 }
335 
336 
337 Any SAL_CALL
339 {
340  Any aRet = cppu::queryInterface( rType,
341  static_cast< XPropertySetInfo* >(this) );
342  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
343 }
344 
345 
346 Property SAL_CALL
348 {
349  auto pProp = std::find_if(m_seq.begin(), m_seq.end(),
350  [&aName](const Property& rProp) { return rProp.Name == aName; });
351  if (pProp != m_seq.end())
352  return *pProp;
353 
354  throw UnknownPropertyException( THROW_WHERE );
355 }
356 
357 
358 Sequence< Property > SAL_CALL
360 {
361  return m_seq;
362 }
363 
364 
365 sal_Bool SAL_CALL
367  const OUString& aName )
368 {
369  return std::any_of(m_seq.begin(), m_seq.end(),
370  [&aName](const Property& rProp) { return rProp.Name == aName; });
371 }
372 
373 
374 void FileProvider::initProperties()
375 {
376  osl::MutexGuard aGuard( m_aMutex );
377  if( ! m_xPropertySetInfo.is() )
378  {
379  osl_getLocalHostname( &m_HostName.pData );
380 
381 #if defined ( UNX )
382  m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
383 #elif defined( WNT )
384  m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
385 #else
386  m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
387 #endif
388  osl::Security aSecurity;
389  aSecurity.getHomeDir( m_HomeDirectory );
390 
391  // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
392  // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
393  // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
394  // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
395 
397  m_xPropertySetInfo.set( p );
398  }
399 }
400 
401 
402 // XPropertySet
403 
406 {
407  initProperties();
408  return m_xPropertySetInfo;
409 }
410 
411 
412 void SAL_CALL
413 FileProvider::setPropertyValue( const OUString& aPropertyName,
414  const Any& )
415 {
416  if( !(aPropertyName == "FileSystemNotation" ||
417  aPropertyName == "HomeDirectory" ||
418  aPropertyName == "HostName") )
419  throw UnknownPropertyException( THROW_WHERE );
420 }
421 
422 
423 Any SAL_CALL
425  const OUString& aPropertyName )
426 {
427  initProperties();
428  if( aPropertyName == "FileSystemNotation" )
429  {
430  return Any(m_FileSystemNotation);
431  }
432  else if( aPropertyName == "HomeDirectory" )
433  {
434  return Any(m_HomeDirectory);
435  }
436  else if( aPropertyName == "HostName" )
437  {
438  return Any(m_HostName);
439  }
440  else
441  throw UnknownPropertyException( THROW_WHERE );
442 }
443 
444 
445 void SAL_CALL
447  const OUString&,
449 {
450 }
451 
452 
453 void SAL_CALL
455  const OUString&,
457 {
458 }
459 
460 void SAL_CALL
462  const OUString&,
464 {
465 }
466 
467 
468 void SAL_CALL
470  const OUString&,
472 {
473 }
474 
475 
476 // XFileIdentifierConverter
477 
478 sal_Int32 SAL_CALL
479 FileProvider::getFileProviderLocality( const OUString& BaseURL )
480 {
481  // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
482  // return -1 (mismatch). What is missing is a fast comparison to ASCII,
483  // ignoring case:
484  return BaseURL.getLength() >= 5
485  && (BaseURL[0] == 'F' || BaseURL[0] == 'f')
486  && (BaseURL[1] == 'I' || BaseURL[1] == 'i')
487  && (BaseURL[2] == 'L' || BaseURL[2] == 'l')
488  && (BaseURL[3] == 'E' || BaseURL[3] == 'e')
489  && BaseURL[4] == ':' ?
490  10 : -1;
491 }
492 
493 OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&,
494  const OUString& SystemPath )
495 {
496  OUString aNormalizedPath;
497  if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
498  return OUString();
499 
500  return aNormalizedPath;
501 }
502 
503 OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL )
504 {
505  OUString aSystemPath;
506  if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
507  return OUString();
508 
509  return aSystemPath;
510 }
511 
512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString SAL_CALL getFileURLFromSystemPath(const OUString &BaseURL, const OUString &SystemPath) override
Definition: prov.cxx:493
Type
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: prov.cxx:424
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:461
FileProvider(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: prov.cxx:91
static bool create(const OUString &rURL, const css::uno::Reference< css::ucb::XCommandEnvironment > &rEnv, const css::uno::Reference< css::uno::XComponentContext > &rCtx, Content &rContent)
static css::uno::Reference< css::lang::XSingleServiceFactory > createServiceFactory(const css::uno::Reference< css::lang::XMultiServiceFactory > &rxServiceMgr)
Definition: prov.cxx:143
OUString m_HomeDirectory
Definition: prov.hxx:163
virtual OUString SAL_CALL getImplementationName() override
Definition: prov.cxx:126
OUString Name
static css::uno::Reference< css::uno::XInterface > SAL_CALL CreateInstance(const css::uno::Reference< css::lang::XMultiServiceFactory > &xMultiServiceFactory)
Definition: prov.cxx:154
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: prov.cxx:413
static OUString getImplementationName_static()
Definition: filtask.cxx:2946
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: prov.cxx:469
virtual sal_Int32 SAL_CALL getFileProviderLocality(const OUString &BaseURL) override
Definition: prov.cxx:479
char sal_Char
virtual Any SAL_CALL queryInterface(const Type &aType) override
Definition: prov.cxx:338
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: prov.cxx:137
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: prov.hxx:158
err
sal_Int32 m_FileSystemNotation
Definition: prov.hxx:164
SAL_DLLPUBLIC_EXPORT void * ucpfile_component_getFactory(const sal_Char *pImplName, void *pServiceManager, void *)
Definition: prov.cxx:55
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
Definition: prov.cxx:110
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL createContentIdentifier(const OUString &ContentId) override
Definition: prov.cxx:256
virtual void SAL_CALL acquire() override
Definition: prov.cxx:322
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:199
unsigned char sal_Bool
static css::uno::Sequence< OUString > getSupportedServiceNames_static()
Definition: filtask.cxx:2953
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
Definition: prov.cxx:166
Sequence< Property > m_seq
Definition: prov.cxx:298
virtual ~FileProvider() override
Definition: prov.cxx:97
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
virtual void SAL_CALL release() override
Definition: prov.cxx:330
osl::Mutex m_aMutex
Definition: prov.hxx:161
css::uno::Reference< css::uno::XInterface >(SAL_CALL *ComponentInstantiation)(const css CPPUHELPER_DLLPUBLIC css::uno::Reference< css::lang::XSingleServiceFactory > SAL_CALL createSingleFactory(const css::uno::Reference< css::lang::XMultiServiceFactory > &rServiceManager, const ::rtl::OUString &rImplementationName, ComponentInstantiation pCreateFunction, const css::uno::Sequence< ::rtl::OUString > &rServiceNames, rtl_ModuleCount *pModCount=NULL)
std::unique_ptr< TaskManager > m_pMyShell
Definition: prov.hxx:168
css::uno::Reference< css::ucb::XContent > get() const
#define THROW_WHERE
Definition: prov.cxx:49
static bool getUnqFromUrl(const OUString &Url, OUString &Unq)
Definition: filtask.cxx:1959
void changeScheme(INetProtocol eTargetScheme)
virtual Sequence< Property > SAL_CALL getProperties() override
Definition: prov.cxx:359
tuple config
css::uno::Reference< css::beans::XPropertySetInfo > m_xPropertySetInfo
Definition: prov.hxx:166
OString const aName
virtual Property SAL_CALL getPropertyByName(const OUString &aName) override
Definition: prov.cxx:347
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: prov.cxx:454
friend class BaseContent
Definition: prov.hxx:59
virtual OUString SAL_CALL getSystemPathFromFileURL(const OUString &URL) override
Definition: prov.cxx:503
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: prov.cxx:131
virtual sal_Bool SAL_CALL hasPropertyByName(const OUString &Name) override
Definition: prov.cxx:366
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: prov.cxx:446
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:405
const uno::Reference< uno::XComponentContext > m_xContext