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