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