1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: prov.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
33 #include <osl/security.hxx>
34 #include <osl/file.hxx>
35 #include <osl/socket.h>
36 #include <cppuhelper/factory.hxx>
37 #include <com/sun/star/registry/XRegistryKey.hpp>
38 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/ucb/FileSystemNotation.hpp>
42 #include <com/sun/star/beans/PropertyState.hpp>
43 #include "filglob.hxx"
50 using namespace fileaccess
;
51 using namespace com::sun::star
;
52 using namespace com::sun::star::uno
;
53 using namespace com::sun::star::lang
;
54 using namespace com::sun::star::beans
;
55 using namespace com::sun::star::ucb
;
56 using namespace com::sun::star::container
;
58 //=========================================================================
59 static sal_Bool
writeInfo( void * pRegistryKey
,
60 const rtl::OUString
& rImplementationName
,
61 Sequence
< rtl::OUString
> const & rServiceNames
)
63 rtl::OUString
aKeyName( rtl::OUString::createFromAscii( "/" ) );
64 aKeyName
+= rImplementationName
;
65 aKeyName
+= rtl::OUString::createFromAscii( "/UNO/SERVICES" );
67 Reference
< registry::XRegistryKey
> xKey
;
70 xKey
= static_cast< registry::XRegistryKey
* >(
71 pRegistryKey
)->createKey( aKeyName
);
73 catch ( registry::InvalidRegistryException
const & )
80 sal_Bool bSuccess
= sal_True
;
82 for ( sal_Int32 n
= 0; n
< rServiceNames
.getLength(); ++n
)
86 xKey
->createKey( rServiceNames
[ n
] );
88 catch ( registry::InvalidRegistryException
const & )
97 //=========================================================================
98 extern "C" void SAL_CALL
component_getImplementationEnvironment(
99 const sal_Char
** ppEnvTypeName
, uno_Environment
** )
101 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
104 //=========================================================================
105 extern "C" sal_Bool SAL_CALL
component_writeInfo( void *, void * pRegistryKey
)
107 return pRegistryKey
&&
109 //////////////////////////////////////////////////////////////////////
110 // File Content Provider.
111 //////////////////////////////////////////////////////////////////////
113 writeInfo( pRegistryKey
,
114 fileaccess::shell::getImplementationName_static(),
115 fileaccess::shell::getSupportedServiceNames_static() );
118 //=========================================================================
119 extern "C" void * SAL_CALL
component_getFactory(
120 const sal_Char
* pImplName
, void * pServiceManager
, void * )
124 Reference
< XMultiServiceFactory
> xSMgr(
125 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
) );
126 Reference
< XSingleServiceFactory
> xFactory
;
128 //////////////////////////////////////////////////////////////////////
129 // File Content Provider.
130 //////////////////////////////////////////////////////////////////////
132 if ( fileaccess::shell::getImplementationName_static().
133 compareToAscii( pImplName
) == 0 )
135 xFactory
= FileProvider::createServiceFactory( xSMgr
);
138 //////////////////////////////////////////////////////////////////////
143 pRet
= xFactory
.get();
149 /****************************************************************************/
155 /****************************************************************************/
159 FileProvider::FileProvider( const Reference
< XMultiServiceFactory
>& xMultiServiceFactory
)
160 : m_xMultiServiceFactory( xMultiServiceFactory
),
166 FileProvider::~FileProvider()
173 //////////////////////////////////////////////////////////////////////////
175 //////////////////////////////////////////////////////////////////////////
178 FileProvider::acquire(
182 OWeakObject::acquire();
187 FileProvider::release(
191 OWeakObject::release();
196 FileProvider::queryInterface(
198 throw( RuntimeException
)
200 Any aRet
= cppu::queryInterface(
202 SAL_STATIC_CAST( XContentProvider
*, this ),
203 SAL_STATIC_CAST( XInitialization
*, this ),
204 SAL_STATIC_CAST( XContentIdentifierFactory
*, this ),
205 SAL_STATIC_CAST( XServiceInfo
*, this ),
206 SAL_STATIC_CAST( XTypeProvider
*, this ),
207 SAL_STATIC_CAST( XFileIdentifierConverter
*,this ),
208 SAL_STATIC_CAST( XPropertySet
*, this ) );
209 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
212 ///////////////////////////////////////////////////////////////////////////////
215 void SAL_CALL
FileProvider::init()
218 m_pMyShell
= new shell( m_xMultiServiceFactory
, this, sal_True
);
223 FileProvider::initialize(
224 const Sequence
< Any
>& aArguments
)
225 throw (Exception
, RuntimeException
)
228 rtl::OUString config
;
229 if( aArguments
.getLength() > 0 &&
230 (aArguments
[0] >>= config
) &&
231 config
.compareToAscii("NoConfig") == 0 )
232 m_pMyShell
= new shell( m_xMultiServiceFactory
, this, sal_False
);
234 m_pMyShell
= new shell( m_xMultiServiceFactory
, this, sal_True
);
239 ////////////////////////////////////////////////////////////////////////////////
241 // XTypeProvider methods.
244 XTYPEPROVIDER_IMPL_7( FileProvider
,
248 XContentIdentifierFactory
,
250 XFileIdentifierConverter
,
254 ////////////////////////////////////////////////////////////////////////////////
255 // XServiceInfo methods.
257 rtl::OUString SAL_CALL
258 FileProvider::getImplementationName()
259 throw( RuntimeException
)
261 return fileaccess::shell::getImplementationName_static();
266 FileProvider::supportsService(
267 const rtl::OUString
& ServiceName
)
268 throw( RuntimeException
)
270 return ServiceName
== rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" );
274 Sequence
< rtl::OUString
> SAL_CALL
275 FileProvider::getSupportedServiceNames(
277 throw( RuntimeException
)
279 return fileaccess::shell::getSupportedServiceNames_static();
284 Reference
< XSingleServiceFactory
> SAL_CALL
285 FileProvider::createServiceFactory(
286 const Reference
< XMultiServiceFactory
>& rxServiceMgr
)
289 * Create a single service factory.<BR>
290 * Note: The function pointer ComponentInstantiation points to a function throws Exception.
292 * @param rServiceManager the service manager used by the implementation.
293 * @param rImplementationName the implementation name. An empty string is possible.
294 * @param ComponentInstantiation the function pointer to create an object.
295 * @param rServiceNames the service supported by the implementation.
296 * @return a factory that support the interfaces XServiceProvider, XServiceInfo
297 * XSingleServiceFactory and XComponent.
299 * @see createOneInstanceFactory
302 * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory
304 * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager,
305 * const ::rtl::OUString & rImplementationName,
306 * ComponentInstantiation pCreateFunction,
308 * const ::com::sun::star::Sequence< ::rtl::OUString > & rServiceNames
312 return Reference
< XSingleServiceFactory
> ( cppu::createSingleFactory(
314 fileaccess::shell::getImplementationName_static(),
315 FileProvider::CreateInstance
,
316 fileaccess::shell::getSupportedServiceNames_static() ) );
319 Reference
< XInterface
> SAL_CALL
320 FileProvider::CreateInstance(
321 const Reference
< XMultiServiceFactory
>& xMultiServiceFactory
)
323 XServiceInfo
* xP
= (XServiceInfo
*) new FileProvider( xMultiServiceFactory
);
324 return Reference
< XInterface
>::query( xP
);
329 ////////////////////////////////////////////////////////////////////////////////
331 ////////////////////////////////////////////////////////////////////////////////
334 Reference
< XContent
> SAL_CALL
335 FileProvider::queryContent(
336 const Reference
< XContentIdentifier
>& xIdentifier
)
337 throw( IllegalIdentifierException
,
342 sal_Bool err
= m_pMyShell
->getUnqFromUrl( xIdentifier
->getContentIdentifier(),
346 throw IllegalIdentifierException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ), uno::Reference
< uno::XInterface
>() );
348 return Reference
< XContent
>( new BaseContent( m_pMyShell
,xIdentifier
,aUnc
) );
354 FileProvider::compareContentIds(
355 const Reference
< XContentIdentifier
>& Id1
,
356 const Reference
< XContentIdentifier
>& Id2
)
357 throw( RuntimeException
)
360 rtl::OUString aUrl1
= Id1
->getContentIdentifier();
361 rtl::OUString aUrl2
= Id2
->getContentIdentifier();
363 sal_Int32 iComp
= aUrl1
.compareTo( aUrl2
);
367 rtl::OUString aPath1
, aPath2
;
369 m_pMyShell
->getUnqFromUrl( aUrl1
, aPath1
);
370 m_pMyShell
->getUnqFromUrl( aUrl2
, aPath2
);
372 osl::FileBase::RC error
;
373 osl::DirectoryItem aItem1
, aItem2
;
375 error
= osl::DirectoryItem::get( aPath1
, aItem1
);
376 if ( error
== osl::FileBase::E_None
)
377 error
= osl::DirectoryItem::get( aPath2
, aItem2
);
379 if ( error
!= osl::FileBase::E_None
)
382 osl::FileStatus
aStatus1( FileStatusMask_FileURL
);
383 osl::FileStatus
aStatus2( FileStatusMask_FileURL
);
384 error
= aItem1
.getFileStatus( aStatus1
);
385 if ( error
== osl::FileBase::E_None
)
386 error
= aItem2
.getFileStatus( aStatus2
);
388 if ( error
== osl::FileBase::E_None
)
390 iComp
= aStatus1
.getFileURL().compareTo( aStatus2
.getFileURL() );
392 // Quick hack for Windows to threat all file systems as case insensitive
396 error
= osl::FileBase::getSystemPathFromFileURL( aStatus1
.getFileURL(), aPath1
);
397 if ( error
== osl::FileBase::E_None
)
398 error
= osl::FileBase::getSystemPathFromFileURL( aStatus2
.getFileURL(), aPath2
);
400 if ( error
== osl::FileBase::E_None
)
401 iComp
= rtl_ustr_compareIgnoreAsciiCase( aPath1
.getStr(), aPath2
.getStr() );
412 Reference
< XContentIdentifier
> SAL_CALL
413 FileProvider::createContentIdentifier(
414 const rtl::OUString
& ContentId
)
415 throw( RuntimeException
)
418 FileContentIdentifier
* p
= new FileContentIdentifier( m_pMyShell
,ContentId
,false );
419 return Reference
< XContentIdentifier
>( p
);
424 //XPropertySetInfoImpl
426 class XPropertySetInfoImpl2
427 : public cppu::OWeakObject
,
428 public XPropertySetInfo
431 XPropertySetInfoImpl2();
432 ~XPropertySetInfoImpl2();
438 throw( RuntimeException
);
440 virtual void SAL_CALL
445 virtual void SAL_CALL
451 virtual Sequence
< Property
> SAL_CALL
454 throw( RuntimeException
);
456 virtual Property SAL_CALL
458 const rtl::OUString
& aName
)
459 throw( UnknownPropertyException
,
462 virtual sal_Bool SAL_CALL
463 hasPropertyByName( const rtl::OUString
& Name
)
464 throw( RuntimeException
);
468 Sequence
< Property
> m_seq
;
472 XPropertySetInfoImpl2::XPropertySetInfoImpl2()
475 m_seq
[0] = Property( rtl::OUString::createFromAscii( "HostName" ),
477 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
478 PropertyAttribute::READONLY
);
480 m_seq
[1] = Property( rtl::OUString::createFromAscii( "HomeDirectory" ),
482 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
483 PropertyAttribute::READONLY
);
485 m_seq
[2] = Property( rtl::OUString::createFromAscii( "FileSystemNotation" ),
487 getCppuType( static_cast< sal_Int32
* >( 0 ) ),
488 PropertyAttribute::READONLY
);
492 XPropertySetInfoImpl2::~XPropertySetInfoImpl2()
499 XPropertySetInfoImpl2::acquire(
503 OWeakObject::acquire();
508 XPropertySetInfoImpl2::release(
512 OWeakObject::release();
517 XPropertySetInfoImpl2::queryInterface(
519 throw( RuntimeException
)
521 Any aRet
= cppu::queryInterface( rType
,
522 SAL_STATIC_CAST( XPropertySetInfo
*,this) );
523 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
528 XPropertySetInfoImpl2::getPropertyByName(
529 const rtl::OUString
& aName
)
530 throw( UnknownPropertyException
,
533 for( sal_Int32 i
= 0; i
< m_seq
.getLength(); ++i
)
534 if( m_seq
[i
].Name
== aName
)
537 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ), uno::Reference
< uno::XInterface
>() );
542 Sequence
< Property
> SAL_CALL
543 XPropertySetInfoImpl2::getProperties(
545 throw( RuntimeException
)
552 XPropertySetInfoImpl2::hasPropertyByName(
553 const rtl::OUString
& aName
)
554 throw( RuntimeException
)
556 for( sal_Int32 i
= 0; i
< m_seq
.getLength(); ++i
)
557 if( m_seq
[i
].Name
== aName
)
566 void SAL_CALL
FileProvider::initProperties( void )
568 osl::MutexGuard
aGuard( m_aMutex
);
569 if( ! m_xPropertySetInfo
.is() )
571 osl_getLocalHostname( &m_HostName
.pData
);
574 m_FileSystemNotation
= FileSystemNotation::UNIX_NOTATION
;
575 #elif defined( WNT ) || defined( OS2 )
576 m_FileSystemNotation
= FileSystemNotation::DOS_NOTATION
;
578 m_FileSystemNotation
= FileSystemNotation::UNKNOWN_NOTATION
;
580 osl::Security aSecurity
;
581 aSecurity
.getHomeDir( m_HomeDirectory
);
583 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0;
584 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1;
585 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2;
586 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3;
588 XPropertySetInfoImpl2
* p
= new XPropertySetInfoImpl2();
589 m_xPropertySetInfo
= Reference
< XPropertySetInfo
>( p
);
596 Reference
< XPropertySetInfo
> SAL_CALL
597 FileProvider::getPropertySetInfo( )
598 throw( RuntimeException
)
601 return m_xPropertySetInfo
;
606 FileProvider::setPropertyValue( const rtl::OUString
& aPropertyName
,
608 throw( UnknownPropertyException
,
609 PropertyVetoException
,
610 IllegalArgumentException
,
611 WrappedTargetException
,
614 if( aPropertyName
.compareToAscii( "FileSystemNotation" ) == 0 ||
615 aPropertyName
.compareToAscii( "HomeDirectory" ) == 0 ||
616 aPropertyName
.compareToAscii( "HostName" ) == 0 )
619 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ), uno::Reference
< uno::XInterface
>() );
625 FileProvider::getPropertyValue(
626 const rtl::OUString
& aPropertyName
)
627 throw( UnknownPropertyException
,
628 WrappedTargetException
,
632 if( aPropertyName
.compareToAscii( "FileSystemNotation" ) == 0 )
635 aAny
<<= m_FileSystemNotation
;
638 else if( aPropertyName
.compareToAscii( "HomeDirectory" ) == 0 )
641 aAny
<<= m_HomeDirectory
;
644 else if( aPropertyName
.compareToAscii( "HostName" ) == 0 )
651 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ), uno::Reference
< uno::XInterface
>() );
656 FileProvider::addPropertyChangeListener(
657 const rtl::OUString
&,
658 const Reference
< XPropertyChangeListener
>& )
659 throw( UnknownPropertyException
,
660 WrappedTargetException
,
668 FileProvider::removePropertyChangeListener(
669 const rtl::OUString
&,
670 const Reference
< XPropertyChangeListener
>& )
671 throw( UnknownPropertyException
,
672 WrappedTargetException
,
679 FileProvider::addVetoableChangeListener(
680 const rtl::OUString
&,
681 const Reference
< XVetoableChangeListener
>& )
682 throw( UnknownPropertyException
,
683 WrappedTargetException
,
691 FileProvider::removeVetoableChangeListener(
692 const rtl::OUString
&,
693 const Reference
< XVetoableChangeListener
>& )
694 throw( UnknownPropertyException
,
695 WrappedTargetException
,
703 // XFileIdentifierConverter
706 FileProvider::getFileProviderLocality( const rtl::OUString
& BaseURL
)
707 throw( RuntimeException
)
709 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise
710 // return -1 (missmatch). What is missing is a fast comparison to ASCII,
712 return BaseURL
.getLength() >= 5
713 && (BaseURL
[0] == 'F' || BaseURL
[0] == 'f')
714 && (BaseURL
[1] == 'I' || BaseURL
[1] == 'i')
715 && (BaseURL
[2] == 'L' || BaseURL
[2] == 'l')
716 && (BaseURL
[3] == 'E' || BaseURL
[3] == 'e')
717 && BaseURL
[4] == ':' ?
721 rtl::OUString SAL_CALL
FileProvider::getFileURLFromSystemPath( const rtl::OUString
&,
722 const rtl::OUString
& SystemPath
)
723 throw( RuntimeException
)
725 rtl::OUString aNormalizedPath
;
726 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath
,aNormalizedPath
) != osl::FileBase::E_None
)
727 return rtl::OUString();
729 return aNormalizedPath
;
732 rtl::OUString SAL_CALL
FileProvider::getSystemPathFromFileURL( const rtl::OUString
& URL
)
733 throw( RuntimeException
)
735 rtl::OUString aSystemPath
;
736 if (osl::FileBase::getSystemPathFromFileURL( URL
,aSystemPath
) != osl::FileBase::E_None
)
737 return rtl::OUString();