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