Line data Source code
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 <comphelper/processfactory.hxx>
24 : #include <com/sun/star/beans/PropertyAttribute.hpp>
25 : #include <com/sun/star/ucb/FileSystemNotation.hpp>
26 : #include <com/sun/star/beans/PropertyState.hpp>
27 : #include <cppuhelper/factory.hxx>
28 : #include <cppuhelper/supportsservice.hxx>
29 : #include "filglob.hxx"
30 : #include "filid.hxx"
31 : #include "shell.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 333 : extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL ucpfile_component_getFactory(
51 : const sal_Char * pImplName, void * pServiceManager, void * )
52 : {
53 333 : void * pRet = 0;
54 :
55 : Reference< XMultiServiceFactory > xSMgr(
56 333 : reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
57 666 : Reference< XSingleServiceFactory > xFactory;
58 :
59 :
60 : // File Content Provider.
61 :
62 :
63 666 : if ( fileaccess::shell::getImplementationName_static().
64 666 : equalsAscii( pImplName ) )
65 : {
66 333 : xFactory = FileProvider::createServiceFactory( xSMgr );
67 : }
68 :
69 :
70 :
71 333 : if ( xFactory.is() )
72 : {
73 333 : xFactory->acquire();
74 333 : pRet = xFactory.get();
75 : }
76 :
77 666 : return pRet;
78 : }
79 :
80 : /****************************************************************************/
81 : /* */
82 : /* */
83 : /* FileProvider */
84 : /* */
85 : /* */
86 : /****************************************************************************/
87 4701 : FileProvider::FileProvider( const Reference< XComponentContext >& rxContext )
88 : : m_xContext(rxContext)
89 : , m_FileSystemNotation(FileSystemNotation::UNKNOWN_NOTATION)
90 4701 : , m_pMyShell(NULL)
91 : {
92 4701 : }
93 :
94 13998 : FileProvider::~FileProvider()
95 : {
96 4666 : if( m_pMyShell )
97 3456 : delete m_pMyShell;
98 9332 : }
99 :
100 : // XInitialization
101 349490 : void SAL_CALL FileProvider::init()
102 : {
103 349490 : if( ! m_pMyShell )
104 3491 : m_pMyShell = new shell( m_xContext, this, true );
105 349490 : }
106 :
107 :
108 : void SAL_CALL
109 0 : FileProvider::initialize(
110 : const Sequence< Any >& aArguments )
111 : throw (Exception, RuntimeException, std::exception)
112 : {
113 0 : if( ! m_pMyShell ) {
114 0 : OUString config;
115 0 : if( aArguments.getLength() > 0 &&
116 0 : (aArguments[0] >>= config) &&
117 0 : config.equalsAscii("NoConfig") )
118 0 : m_pMyShell = new shell( m_xContext, this, false );
119 : else
120 0 : m_pMyShell = new shell( m_xContext, this, true );
121 : }
122 0 : }
123 :
124 : // XServiceInfo methods.
125 : OUString SAL_CALL
126 2 : FileProvider::getImplementationName()
127 : throw( RuntimeException, std::exception )
128 : {
129 2 : return fileaccess::shell::getImplementationName_static();
130 : }
131 :
132 0 : sal_Bool SAL_CALL FileProvider::supportsService(const OUString& ServiceName )
133 : throw( RuntimeException, std::exception )
134 : {
135 0 : return cppu::supportsService(this, ServiceName);
136 : }
137 :
138 : Sequence< OUString > SAL_CALL
139 0 : FileProvider::getSupportedServiceNames(
140 : void )
141 : throw( RuntimeException, std::exception )
142 : {
143 0 : return fileaccess::shell::getSupportedServiceNames_static();
144 : }
145 :
146 : Reference< XSingleServiceFactory > SAL_CALL
147 333 : FileProvider::createServiceFactory(
148 : const Reference< XMultiServiceFactory >& rxServiceMgr )
149 : {
150 : /**
151 : * Create a single service factory.<BR>
152 : * Note: The function pointer ComponentInstantiation points to a function throws Exception.
153 : *
154 : * @param rServiceManager the service manager used by the implementation.
155 : * @param rImplementationName the implementation name. An empty string is possible.
156 : * @param ComponentInstantiation the function pointer to create an object.
157 : * @param rServiceNames the service supported by the implementation.
158 : * @return a factory that support the interfaces XServiceProvider, XServiceInfo
159 : * XSingleServiceFactory and XComponent.
160 : *
161 : * @see createOneInstanceFactory
162 : */
163 : /*
164 : * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory
165 : * (
166 : * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager,
167 : * const OUString & rImplementationName,
168 : * ComponentInstantiation pCreateFunction,
169 :
170 : * const ::com::sun::star::Sequence< OUString > & rServiceNames
171 : * );
172 : */
173 :
174 : return Reference< XSingleServiceFactory > ( cppu::createSingleFactory(
175 : rxServiceMgr,
176 : fileaccess::shell::getImplementationName_static(),
177 : FileProvider::CreateInstance,
178 333 : fileaccess::shell::getSupportedServiceNames_static() ) );
179 : }
180 :
181 : Reference< XInterface > SAL_CALL
182 4701 : FileProvider::CreateInstance(
183 : const Reference< XMultiServiceFactory >& xMultiServiceFactory )
184 : {
185 4701 : XServiceInfo* xP = (XServiceInfo*) new FileProvider( comphelper::getComponentContext(xMultiServiceFactory) );
186 4701 : return Reference< XInterface >::query( xP );
187 : }
188 :
189 :
190 :
191 :
192 : // XContent
193 :
194 :
195 :
196 : Reference< XContent > SAL_CALL
197 178225 : FileProvider::queryContent(
198 : const Reference< XContentIdentifier >& xIdentifier )
199 : throw( IllegalIdentifierException,
200 : RuntimeException, std::exception)
201 : {
202 178225 : init();
203 178225 : OUString aUnc;
204 178225 : bool err = m_pMyShell->getUnqFromUrl( xIdentifier->getContentIdentifier(),
205 178225 : aUnc );
206 :
207 178225 : if( err )
208 0 : throw IllegalIdentifierException( THROW_WHERE );
209 :
210 178225 : return Reference< XContent >( new BaseContent( m_pMyShell,xIdentifier,aUnc ) );
211 : }
212 :
213 :
214 :
215 : sal_Int32 SAL_CALL
216 1268 : FileProvider::compareContentIds(
217 : const Reference< XContentIdentifier >& Id1,
218 : const Reference< XContentIdentifier >& Id2 )
219 : throw( RuntimeException, std::exception )
220 : {
221 1268 : init();
222 1268 : OUString aUrl1 = Id1->getContentIdentifier();
223 2536 : OUString aUrl2 = Id2->getContentIdentifier();
224 :
225 1268 : sal_Int32 iComp = aUrl1.compareTo( aUrl2 );
226 :
227 1268 : if ( 0 != iComp )
228 : {
229 2478 : OUString aPath1, aPath2;
230 :
231 1246 : m_pMyShell->getUnqFromUrl( aUrl1, aPath1 );
232 1246 : m_pMyShell->getUnqFromUrl( aUrl2, aPath2 );
233 :
234 : osl::FileBase::RC error;
235 2478 : osl::DirectoryItem aItem1, aItem2;
236 :
237 1246 : error = osl::DirectoryItem::get( aPath1, aItem1 );
238 1246 : if ( error == osl::FileBase::E_None )
239 1242 : error = osl::DirectoryItem::get( aPath2, aItem2 );
240 :
241 1246 : if ( error != osl::FileBase::E_None )
242 14 : return iComp;
243 :
244 2464 : osl::FileStatus aStatus1( osl_FileStatus_Mask_FileURL );
245 2464 : osl::FileStatus aStatus2( osl_FileStatus_Mask_FileURL );
246 1232 : error = aItem1.getFileStatus( aStatus1 );
247 1232 : if ( error == osl::FileBase::E_None )
248 1232 : error = aItem2.getFileStatus( aStatus2 );
249 :
250 1232 : if ( error == osl::FileBase::E_None )
251 : {
252 1232 : iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() );
253 :
254 : // Quick hack for Windows to threat all file systems as case insensitive
255 : #ifdef WNT
256 : if ( 0 != iComp )
257 : {
258 : error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 );
259 : if ( error == osl::FileBase::E_None )
260 : error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 );
261 :
262 : if ( error == osl::FileBase::E_None )
263 : iComp = rtl_ustr_compareIgnoreAsciiCase( aPath1.getStr(), aPath2.getStr() );
264 : }
265 : #endif
266 1232 : }
267 : }
268 :
269 2522 : return iComp;
270 : }
271 :
272 :
273 :
274 : Reference< XContentIdentifier > SAL_CALL
275 169997 : FileProvider::createContentIdentifier(
276 : const OUString& ContentId )
277 : throw( RuntimeException, std::exception )
278 : {
279 169997 : init();
280 169997 : FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ContentId,false );
281 169997 : return Reference< XContentIdentifier >( p );
282 : }
283 :
284 :
285 :
286 : //XPropertySetInfoImpl
287 :
288 : class XPropertySetInfoImpl2
289 : : public cppu::OWeakObject,
290 : public XPropertySetInfo
291 : {
292 : public:
293 : XPropertySetInfoImpl2();
294 : virtual ~XPropertySetInfoImpl2();
295 :
296 : // XInterface
297 : virtual Any SAL_CALL
298 : queryInterface(
299 : const Type& aType )
300 : throw( RuntimeException, std::exception) SAL_OVERRIDE;
301 :
302 : virtual void SAL_CALL
303 : acquire(
304 : void )
305 : throw() SAL_OVERRIDE;
306 :
307 : virtual void SAL_CALL
308 : release(
309 : void )
310 : throw() SAL_OVERRIDE;
311 :
312 :
313 : virtual Sequence< Property > SAL_CALL
314 : getProperties(
315 : void )
316 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
317 :
318 : virtual Property SAL_CALL
319 : getPropertyByName(
320 : const OUString& aName )
321 : throw( UnknownPropertyException,
322 : RuntimeException, std::exception) SAL_OVERRIDE;
323 :
324 : virtual sal_Bool SAL_CALL
325 : hasPropertyByName( const OUString& Name )
326 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
327 :
328 :
329 : private:
330 : Sequence< Property > m_seq;
331 : };
332 :
333 :
334 2 : XPropertySetInfoImpl2::XPropertySetInfoImpl2()
335 2 : : m_seq( 3 )
336 : {
337 4 : m_seq[0] = Property( OUString("HostName"),
338 : -1,
339 2 : cppu::UnoType<OUString>::get(),
340 2 : PropertyAttribute::READONLY );
341 :
342 4 : m_seq[1] = Property( OUString("HomeDirectory"),
343 : -1,
344 2 : cppu::UnoType<OUString>::get(),
345 2 : PropertyAttribute::READONLY );
346 :
347 4 : m_seq[2] = Property( OUString("FileSystemNotation"),
348 : -1,
349 2 : cppu::UnoType<sal_Int32>::get(),
350 2 : PropertyAttribute::READONLY );
351 2 : }
352 :
353 :
354 4 : XPropertySetInfoImpl2::~XPropertySetInfoImpl2()
355 : {
356 : // nothing
357 4 : }
358 :
359 :
360 : void SAL_CALL
361 14 : XPropertySetInfoImpl2::acquire(
362 : void )
363 : throw()
364 : {
365 14 : OWeakObject::acquire();
366 14 : }
367 :
368 :
369 : void SAL_CALL
370 14 : XPropertySetInfoImpl2::release(
371 : void )
372 : throw()
373 : {
374 14 : OWeakObject::release();
375 14 : }
376 :
377 :
378 : Any SAL_CALL
379 2 : XPropertySetInfoImpl2::queryInterface(
380 : const Type& rType )
381 : throw( RuntimeException, std::exception )
382 : {
383 : Any aRet = cppu::queryInterface( rType,
384 2 : (static_cast< XPropertySetInfo* >(this)) );
385 2 : return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
386 : }
387 :
388 :
389 : Property SAL_CALL
390 0 : XPropertySetInfoImpl2::getPropertyByName(
391 : const OUString& aName )
392 : throw( UnknownPropertyException,
393 : RuntimeException, std::exception)
394 : {
395 0 : for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
396 0 : if( m_seq[i].Name == aName )
397 0 : return m_seq[i];
398 :
399 0 : throw UnknownPropertyException( THROW_WHERE );
400 : }
401 :
402 :
403 :
404 : Sequence< Property > SAL_CALL
405 4 : XPropertySetInfoImpl2::getProperties(
406 : void )
407 : throw( RuntimeException, std::exception )
408 : {
409 4 : return m_seq;
410 : }
411 :
412 :
413 : sal_Bool SAL_CALL
414 0 : XPropertySetInfoImpl2::hasPropertyByName(
415 : const OUString& aName )
416 : throw( RuntimeException, std::exception )
417 : {
418 0 : for( sal_Int32 i = 0; i < m_seq.getLength(); ++i )
419 0 : if( m_seq[i].Name == aName )
420 0 : return true;
421 0 : return false;
422 : }
423 :
424 :
425 :
426 :
427 :
428 6 : void SAL_CALL FileProvider::initProperties( void )
429 : {
430 6 : osl::MutexGuard aGuard( m_aMutex );
431 6 : if( ! m_xPropertySetInfo.is() )
432 : {
433 2 : osl_getLocalHostname( &m_HostName.pData );
434 :
435 : #if defined ( UNX )
436 2 : m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION;
437 : #elif defined( WNT )
438 : m_FileSystemNotation = FileSystemNotation::DOS_NOTATION;
439 : #else
440 : m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION;
441 : #endif
442 2 : osl::Security aSecurity;
443 2 : aSecurity.getHomeDir( m_HomeDirectory );
444 :
445 : // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
446 : // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
447 : // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
448 : // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
449 :
450 2 : XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2();
451 2 : m_xPropertySetInfo = Reference< XPropertySetInfo >( p );
452 6 : }
453 6 : }
454 :
455 :
456 : // XPropertySet
457 :
458 : Reference< XPropertySetInfo > SAL_CALL
459 4 : FileProvider::getPropertySetInfo( )
460 : throw( RuntimeException, std::exception )
461 : {
462 4 : initProperties();
463 4 : return m_xPropertySetInfo;
464 : }
465 :
466 :
467 : void SAL_CALL
468 0 : FileProvider::setPropertyValue( const OUString& aPropertyName,
469 : const Any& )
470 : throw( UnknownPropertyException,
471 : PropertyVetoException,
472 : IllegalArgumentException,
473 : WrappedTargetException,
474 : RuntimeException, std::exception )
475 : {
476 0 : if( aPropertyName.equalsAscii( "FileSystemNotation" ) ||
477 0 : aPropertyName.equalsAscii( "HomeDirectory" ) ||
478 0 : aPropertyName.equalsAscii( "HostName" ) )
479 0 : return;
480 : else
481 0 : throw UnknownPropertyException( THROW_WHERE );
482 : }
483 :
484 :
485 :
486 : Any SAL_CALL
487 2 : FileProvider::getPropertyValue(
488 : const OUString& aPropertyName )
489 : throw( UnknownPropertyException,
490 : WrappedTargetException,
491 : RuntimeException, std::exception )
492 : {
493 2 : initProperties();
494 2 : if( aPropertyName.equalsAscii( "FileSystemNotation" ) )
495 : {
496 0 : Any aAny;
497 0 : aAny <<= m_FileSystemNotation;
498 0 : return aAny;
499 : }
500 2 : else if( aPropertyName.equalsAscii( "HomeDirectory" ) )
501 : {
502 0 : Any aAny;
503 0 : aAny <<= m_HomeDirectory;
504 0 : return aAny;
505 : }
506 2 : else if( aPropertyName.equalsAscii( "HostName" ) )
507 : {
508 2 : Any aAny;
509 2 : aAny <<= m_HostName;
510 2 : return aAny;
511 : }
512 : else
513 0 : throw UnknownPropertyException( THROW_WHERE );
514 : }
515 :
516 :
517 : void SAL_CALL
518 0 : FileProvider::addPropertyChangeListener(
519 : const OUString&,
520 : const Reference< XPropertyChangeListener >& )
521 : throw( UnknownPropertyException,
522 : WrappedTargetException,
523 : RuntimeException, std::exception)
524 : {
525 0 : return;
526 : }
527 :
528 :
529 : void SAL_CALL
530 0 : FileProvider::removePropertyChangeListener(
531 : const OUString&,
532 : const Reference< XPropertyChangeListener >& )
533 : throw( UnknownPropertyException,
534 : WrappedTargetException,
535 : RuntimeException, std::exception )
536 : {
537 0 : return;
538 : }
539 :
540 : void SAL_CALL
541 0 : FileProvider::addVetoableChangeListener(
542 : const OUString&,
543 : const Reference< XVetoableChangeListener >& )
544 : throw( UnknownPropertyException,
545 : WrappedTargetException,
546 : RuntimeException, std::exception )
547 : {
548 0 : return;
549 : }
550 :
551 :
552 : void SAL_CALL
553 0 : FileProvider::removeVetoableChangeListener(
554 : const OUString&,
555 : const Reference< XVetoableChangeListener >& )
556 : throw( UnknownPropertyException,
557 : WrappedTargetException,
558 : RuntimeException, std::exception)
559 : {
560 0 : return;
561 : }
562 :
563 :
564 :
565 : // XFileIdentifierConverter
566 :
567 : sal_Int32 SAL_CALL
568 2 : FileProvider::getFileProviderLocality( const OUString& BaseURL )
569 : throw( RuntimeException, std::exception )
570 : {
571 : // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
572 : // return -1 (missmatch). What is missing is a fast comparison to ASCII,
573 : // ignoring case:
574 2 : return BaseURL.getLength() >= 5
575 2 : && (BaseURL[0] == 'F' || BaseURL[0] == 'f')
576 2 : && (BaseURL[1] == 'I' || BaseURL[1] == 'i')
577 2 : && (BaseURL[2] == 'L' || BaseURL[2] == 'l')
578 2 : && (BaseURL[3] == 'E' || BaseURL[3] == 'e')
579 2 : && BaseURL[4] == ':' ?
580 4 : 10 : -1;
581 : }
582 :
583 47806 : OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const OUString&,
584 : const OUString& SystemPath )
585 : throw( RuntimeException, std::exception )
586 : {
587 47806 : OUString aNormalizedPath;
588 47806 : if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None )
589 0 : return OUString();
590 :
591 47806 : return aNormalizedPath;
592 : }
593 :
594 102431 : OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const OUString& URL )
595 : throw( RuntimeException, std::exception )
596 : {
597 102431 : OUString aSystemPath;
598 102431 : if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None )
599 0 : return OUString();
600 :
601 102431 : return aSystemPath;
602 : }
603 :
604 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|