xref: /trunk/main/svl/source/fsstor/fsstorage.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_svl.hxx"
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/embed/ElementModes.hpp>
32 #include <com/sun/star/embed/XTransactedObject.hpp>
33 #include <com/sun/star/ucb/XProgressHandler.hpp>
34 #include <com/sun/star/ucb/XContentAccess.hpp>
35 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
36 
37 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
38 #include <com/sun/star/ucb/InteractiveIOException.hpp>
39 #endif
40 #include <com/sun/star/ucb/IOErrorCode.hpp>
41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 #include <com/sun/star/container/XEnumerationAccess.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/util/XChangesBatch.hpp>
45 #include <com/sun/star/util/XCloneable.hpp>
46 #include <com/sun/star/lang/XUnoTunnel.hpp>
47 #include <com/sun/star/lang/XComponent.hpp>
48 #include <com/sun/star/lang/DisposedException.hpp>
49 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
50 #include <com/sun/star/io/IOException.hpp>
51 #include <com/sun/star/io/XTruncate.hpp>
52 #include <com/sun/star/sdbc/XResultSet.hpp>
53 #include <com/sun/star/sdbc/XRow.hpp>
54 
55 
56 #ifndef _COMPHELPER_PROCESSFACTORY_HXX
57 #include <comphelper/processfactory.hxx>
58 #endif
59 #include <comphelper/storagehelper.hxx>
60 #include <cppuhelper/typeprovider.hxx>
61 #include <cppuhelper/exc_hlp.hxx>
62 
63 #include <tools/urlobj.hxx>
64 #include <unotools/ucbhelper.hxx>
65 #include <unotools/ucbstreamhelper.hxx>
66 #include <unotools/streamwrap.hxx>
67 #include <ucbhelper/fileidentifierconverter.hxx>
68 #include <ucbhelper/contentbroker.hxx>
69 #include <ucbhelper/content.hxx>
70 
71 #include "fsstorage.hxx"
72 #include "oinputstreamcontainer.hxx"
73 #include "ostreamcontainer.hxx"
74 
75 using namespace ::com::sun::star;
76 
77 //=========================================================
78 
79 // TODO: move to a standard helper
80 sal_Bool isLocalFile_Impl( ::rtl::OUString aURL )
81 {
82 	::rtl::OUString aSystemPath;
83     ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
84     if ( !pBroker )
85 		throw uno::RuntimeException();
86 
87 	uno::Reference< ucb::XContentProviderManager > xManager =
88 				pBroker->getContentProviderManagerInterface();
89 	try
90 	{
91 		aSystemPath = ::ucbhelper::getSystemPathFromFileURL( xManager, aURL );
92 	}
93 	catch ( uno::Exception& )
94 	{
95 	}
96 
97 	return ( aSystemPath.getLength() != 0 );
98 }
99 
100 
101 //=========================================================
102 
103 struct FSStorage_Impl
104 {
105 	::rtl::OUString m_aURL;
106 
107 	::ucbhelper::Content* m_pContent;
108 	sal_Int32 m_nMode;
109 
110 	::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners
111 	::cppu::OTypeCollection* m_pTypeCollection;
112 
113 	uno::Reference< lang::XMultiServiceFactory > m_xFactory;
114 
115 
116 	FSStorage_Impl( const ::rtl::OUString& aURL, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory )
117 	: m_aURL( aURL )
118 	, m_pContent( NULL )
119 	, m_nMode( nMode )
120 	, m_pListenersContainer( NULL )
121 	, m_pTypeCollection( NULL )
122 	, m_xFactory( xFactory )
123 	{
124 		OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" );
125 	}
126 
127 	FSStorage_Impl( const ::ucbhelper::Content& aContent, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory )
128 	: m_aURL( aContent.getURL() )
129 	, m_pContent( new ::ucbhelper::Content( aContent ) )
130 	, m_nMode( nMode )
131 	, m_pListenersContainer( NULL )
132 	, m_pTypeCollection( NULL )
133 	, m_xFactory( xFactory )
134 	{
135 		OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" );
136 	}
137 
138 	~FSStorage_Impl();
139 };
140 
141 //=========================================================
142 
143 FSStorage_Impl::~FSStorage_Impl()
144 {
145 	if ( m_pListenersContainer )
146 		delete m_pListenersContainer;
147 	if ( m_pTypeCollection )
148 		delete m_pTypeCollection;
149 	if ( m_pContent )
150 		delete m_pContent;
151 }
152 
153 //=====================================================
154 // FSStorage implementation
155 //=====================================================
156 
157 //-----------------------------------------------
158 FSStorage::FSStorage( const ::ucbhelper::Content& aContent,
159 					sal_Int32 nMode,
160 					uno::Sequence< beans::PropertyValue >,
161 					uno::Reference< lang::XMultiServiceFactory > xFactory )
162 : m_pImpl( new FSStorage_Impl( aContent, nMode, xFactory ) )
163 {
164 	// TODO: use properties
165 	if ( !xFactory.is() )
166 		throw uno::RuntimeException();
167 
168 	GetContent();
169 }
170 
171 //-----------------------------------------------
172 FSStorage::~FSStorage()
173 {
174 	{
175 		::osl::MutexGuard aGuard( m_aMutex );
176 		m_refCount++; // to call dispose
177 		try {
178 			dispose();
179 		}
180 		catch( uno::RuntimeException& )
181 		{}
182 	}
183 }
184 
185 //-----------------------------------------------
186 sal_Bool FSStorage::MakeFolderNoUI( const String& rFolder, sal_Bool )
187 {
188    	INetURLObject aURL( rFolder );
189 	::rtl::OUString aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
190 	aURL.removeSegment();
191 	::ucbhelper::Content aParent;
192 	::ucbhelper::Content aResultContent;
193 
194    	if ( ::ucbhelper::Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ),
195 								 uno::Reference< ucb::XCommandEnvironment >(),
196 								 aParent ) )
197 		return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent, sal_False );
198 
199 	return sal_False;
200 }
201 
202 //-----------------------------------------------
203 ::ucbhelper::Content* FSStorage::GetContent()
204 {
205 	::osl::MutexGuard aGuard( m_aMutex );
206 	if ( !m_pImpl->m_pContent )
207 	{
208 		uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
209 
210 		try
211 		{
212 			m_pImpl->m_pContent = new ::ucbhelper::Content( m_pImpl->m_aURL, xDummyEnv );
213 		}
214 		catch( uno::Exception& )
215 		{
216 		}
217 	}
218 
219 	return m_pImpl->m_pContent;
220 }
221 
222 //-----------------------------------------------
223 void FSStorage::CopyStreamToSubStream( const ::rtl::OUString& aSourceURL,
224 										const uno::Reference< embed::XStorage >& xDest,
225 										const ::rtl::OUString& aNewEntryName )
226 {
227 	if ( !xDest.is() )
228 		throw uno::RuntimeException();
229 
230 	uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
231 	::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv );
232 	uno::Reference< io::XInputStream > xSourceInput = aSourceContent.openStream();
233 
234 	if ( !xSourceInput.is() )
235 		throw io::IOException(); // TODO: error handling
236 
237 	uno::Reference< io::XStream > xSubStream = xDest->openStreamElement(
238 												aNewEntryName,
239 												embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
240 	if ( !xSubStream.is() )
241 		throw uno::RuntimeException();
242 
243 	uno::Reference< io::XOutputStream > xDestOutput = xSubStream->getOutputStream();
244 	if ( !xDestOutput.is() )
245 		throw uno::RuntimeException();
246 
247 	::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput, xDestOutput );
248 	xDestOutput->closeOutput();
249 }
250 
251 //-----------------------------------------------
252 void FSStorage::CopyContentToStorage_Impl( ::ucbhelper::Content* pContent, const uno::Reference< embed::XStorage >& xDest )
253 {
254 	if ( !pContent )
255 		throw uno::RuntimeException();
256 
257 	// get list of contents of the Content
258 	// create cursor for access to children
259 	uno::Sequence< ::rtl::OUString > aProps( 2 );
260 	::rtl::OUString* pProps = aProps.getArray();
261 	pProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
262 	pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" );
263 	::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
264 
265 	try
266 	{
267 		uno::Reference< sdbc::XResultSet > xResultSet = pContent->createCursor( aProps, eInclude );
268 		uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
269 		uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
270 		if ( xResultSet.is() )
271 		{
272 			// go through the list: insert files as streams, insert folders as substorages using recursion
273 			while ( xResultSet->next() )
274 			{
275 				::rtl::OUString aSourceURL( xRow->getString( 1 ) );
276 				sal_Bool bIsFolder( xRow->getBoolean(2) );
277 
278 				// TODO/LATER: not sure whether the entry name must be encoded
279 				::rtl::OUString aNewEntryName( INetURLObject( aSourceURL ).getName( INetURLObject::LAST_SEGMENT,
280 																					true,
281 																					INetURLObject::NO_DECODE ) );
282 				if ( bIsFolder )
283 				{
284 					uno::Reference< embed::XStorage > xSubStorage = xDest->openStorageElement( aNewEntryName,
285 																								embed::ElementModes::READWRITE );
286 					if ( !xSubStorage.is() )
287 						throw uno::RuntimeException();
288 
289 					uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
290 					::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv );
291 					CopyContentToStorage_Impl( &aSourceContent, xSubStorage );
292 				}
293 				else
294 				{
295 					CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName );
296 				}
297 			}
298 		}
299 
300 		uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY );
301 		if ( xTransact.is() )
302 			xTransact->commit();
303 	}
304 	catch( ucb::InteractiveIOException& r )
305     {
306         if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
307 			OSL_ENSURE( sal_False, "The folder does not exist!\n" );
308 		else
309 			throw;
310     }
311 }
312 
313 //____________________________________________________________________________________________________
314 //	XInterface
315 //____________________________________________________________________________________________________
316 
317 //-----------------------------------------------
318 uno::Any SAL_CALL FSStorage::queryInterface( const uno::Type& rType )
319 		throw( uno::RuntimeException )
320 {
321 	uno::Any aReturn;
322 	aReturn <<= ::cppu::queryInterface
323 				(	rType
324 				,	static_cast<lang::XTypeProvider*> ( this )
325 				,	static_cast<embed::XStorage*> ( this )
326 				,	static_cast<embed::XHierarchicalStorageAccess*> ( this )
327 				,	static_cast<container::XNameAccess*> ( this )
328 				,	static_cast<container::XElementAccess*> ( this )
329 				,	static_cast<lang::XComponent*> ( this )
330 				,	static_cast<beans::XPropertySet*> ( this ) );
331 
332 	if ( aReturn.hasValue() == sal_True )
333 		return aReturn ;
334 
335 	return OWeakObject::queryInterface( rType );
336 }
337 
338 //-----------------------------------------------
339 void SAL_CALL FSStorage::acquire() throw()
340 {
341 	OWeakObject::acquire();
342 }
343 
344 //-----------------------------------------------
345 void SAL_CALL FSStorage::release() throw()
346 {
347 	OWeakObject::release();
348 }
349 
350 //____________________________________________________________________________________________________
351 //	XTypeProvider
352 //____________________________________________________________________________________________________
353 
354 //-----------------------------------------------
355 uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes()
356 		throw( uno::RuntimeException )
357 {
358 	if ( m_pImpl->m_pTypeCollection == NULL )
359 	{
360 		::osl::MutexGuard aGuard( m_aMutex );
361 
362 		if ( m_pImpl->m_pTypeCollection == NULL )
363 		{
364 			m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection
365 								(	::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
366 								,	::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
367 								,	::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL )
368 								,	::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
369 		}
370 	}
371 
372 	return m_pImpl->m_pTypeCollection->getTypes() ;
373 }
374 
375 //-----------------------------------------------
376 uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
377 		throw( uno::RuntimeException )
378 {
379 	static ::cppu::OImplementationId* pID = NULL ;
380 
381 	if ( pID == NULL )
382 	{
383 		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
384 
385 		if ( pID == NULL )
386 		{
387 			static ::cppu::OImplementationId aID( sal_False ) ;
388 			pID = &aID ;
389 		}
390 	}
391 
392 	return pID->getImplementationId() ;
393 
394 }
395 
396 //____________________________________________________________________________________________________
397 //	XStorage
398 //____________________________________________________________________________________________________
399 
400 //-----------------------------------------------
401 void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
402 		throw ( embed::InvalidStorageException,
403 				io::IOException,
404 				lang::IllegalArgumentException,
405 				embed::StorageWrappedTargetException,
406 				uno::RuntimeException )
407 {
408 	::osl::MutexGuard aGuard( m_aMutex );
409 
410 	if ( !m_pImpl )
411 		throw lang::DisposedException();
412 
413 	if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
414 		throw lang::IllegalArgumentException(); // TODO:
415 
416 	if ( !GetContent() )
417 		throw io::IOException(); // TODO: error handling
418 
419 	try
420 	{
421 		CopyContentToStorage_Impl( GetContent(), xDest );
422 	}
423 	catch( embed::InvalidStorageException& )
424 	{
425 		throw;
426 	}
427 	catch( lang::IllegalArgumentException& )
428 	{
429 		throw;
430 	}
431 	catch( embed::StorageWrappedTargetException& )
432 	{
433 		throw;
434 	}
435 	catch( io::IOException& )
436 	{
437 		throw;
438 	}
439 	catch( uno::RuntimeException& )
440 	{
441 		throw;
442 	}
443 	catch( uno::Exception& )
444 	{
445       	uno::Any aCaught( ::cppu::getCaughtException() );
446 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
447 												 uno::Reference< io::XInputStream >(),
448 												 aCaught );
449 	}
450 }
451 
452 //-----------------------------------------------
453 uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement(
454 	const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
455 		throw ( embed::InvalidStorageException,
456 				lang::IllegalArgumentException,
457 				packages::WrongPasswordException,
458 				io::IOException,
459 				embed::StorageWrappedTargetException,
460 				uno::RuntimeException )
461 {
462 	::osl::MutexGuard aGuard( m_aMutex );
463 
464 	if ( !m_pImpl )
465 		throw lang::DisposedException();
466 
467 	if ( !GetContent() )
468 		throw io::IOException(); // TODO: error handling
469 
470 	// TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
471 	INetURLObject aFileURL( m_pImpl->m_aURL );
472 	aFileURL.Append( aStreamName );
473 
474 	if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
475 		throw io::IOException();
476 
477 	if ( ( nOpenMode & embed::ElementModes::NOCREATE )
478 	  && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
479 		throw io::IOException(); // TODO:
480 
481 	uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
482 	uno::Reference< io::XStream > xResult;
483 	try
484 	{
485 		if ( nOpenMode & embed::ElementModes::WRITE )
486 		{
487 			if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
488 			{
489 				uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
490 					m_pImpl->m_xFactory->createInstance(
491 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
492 					uno::UNO_QUERY_THROW );
493 				xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
494 			}
495 			else
496 			{
497 				// TODO: test whether it really works for http and fwp
498 				SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
499 																	  	STREAM_STD_WRITE );
500 				if ( pStream )
501 				{
502 					if ( !pStream->GetError() )
503 						xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
504 					else
505 						delete pStream;
506 				}
507 			}
508 
509 			if ( !xResult.is() )
510 				throw io::IOException();
511 
512 			if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
513 			{
514 				uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
515 				xTrunc->truncate();
516 			}
517 		}
518 		else
519 		{
520 			if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
521 		  	|| !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
522 				throw io::IOException(); // TODO: access denied
523 
524 			::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
525 			uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
526 			xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
527 		}
528 	}
529 	catch( embed::InvalidStorageException& )
530 	{
531 		throw;
532 	}
533 	catch( lang::IllegalArgumentException& )
534 	{
535 		throw;
536 	}
537 	catch( packages::WrongPasswordException& )
538 	{
539 		throw;
540 	}
541 	catch( embed::StorageWrappedTargetException& )
542 	{
543 		throw;
544 	}
545 	catch( io::IOException& )
546 	{
547 		throw;
548 	}
549 	catch( uno::RuntimeException& )
550 	{
551 		throw;
552 	}
553 	catch( uno::Exception& )
554 	{
555       	uno::Any aCaught( ::cppu::getCaughtException() );
556 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
557 												 uno::Reference< io::XInputStream >(),
558 												 aCaught );
559 	}
560 
561 	return xResult;
562 }
563 
564 //-----------------------------------------------
565 uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement(
566 	const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& )
567 		throw ( embed::InvalidStorageException,
568 				lang::IllegalArgumentException,
569 				packages::NoEncryptionException,
570 				packages::WrongPasswordException,
571 				io::IOException,
572 				embed::StorageWrappedTargetException,
573 				uno::RuntimeException )
574 {
575 	throw packages::NoEncryptionException();
576 }
577 
578 //-----------------------------------------------
579 uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement(
580 			const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
581 		throw ( embed::InvalidStorageException,
582 				lang::IllegalArgumentException,
583 				io::IOException,
584 				embed::StorageWrappedTargetException,
585 				uno::RuntimeException )
586 {
587 	::osl::MutexGuard aGuard( m_aMutex );
588 
589 	if ( !m_pImpl )
590 		throw lang::DisposedException();
591 
592 	if ( !GetContent() )
593 		throw io::IOException(); // TODO: error handling
594 
595 	if ( ( nStorageMode & embed::ElementModes::WRITE )
596 	  && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) )
597 	  	throw io::IOException(); // TODO: error handling
598 
599 	// TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
600 	INetURLObject aFolderURL( m_pImpl->m_aURL );
601 	aFolderURL.Append( aStorName );
602 
603 	sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
604 	if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
605 		throw io::IOException(); // TODO:
606 
607 	if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists )
608 		throw io::IOException(); // TODO:
609 
610 	uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
611 	uno::Reference< embed::XStorage > xResult;
612 	try
613 	{
614 		if ( nStorageMode & embed::ElementModes::WRITE )
615 		{
616 			if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists )
617 			{
618 				::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
619 				bFolderExists =
620 					MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
621 			}
622 			else if ( !bFolderExists )
623 			{
624 				bFolderExists =
625 					MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
626 			}
627 		}
628 		else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
629 			throw io::IOException(); // TODO: access denied
630 
631 		if ( !bFolderExists )
632 			throw io::IOException(); // there is no such folder
633 
634 		::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
635 		xResult = uno::Reference< embed::XStorage >(
636 							static_cast< OWeakObject* >( new FSStorage(	aResultContent,
637 																		nStorageMode,
638 																		uno::Sequence< beans::PropertyValue >(),
639 																		m_pImpl->m_xFactory ) ),
640 							uno::UNO_QUERY );
641 	}
642 	catch( embed::InvalidStorageException& )
643 	{
644 		throw;
645 	}
646 	catch( lang::IllegalArgumentException& )
647 	{
648 		throw;
649 	}
650 	catch( embed::StorageWrappedTargetException& )
651 	{
652 		throw;
653 	}
654 	catch( io::IOException& )
655 	{
656 		throw;
657 	}
658 	catch( uno::RuntimeException& )
659 	{
660 		throw;
661 	}
662 	catch( uno::Exception& )
663 	{
664       	uno::Any aCaught( ::cppu::getCaughtException() );
665 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
666 												 uno::Reference< io::XInputStream >(),
667 												 aCaught );
668 	}
669 
670 	return xResult;
671 }
672 
673 //-----------------------------------------------
674 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
675 		throw ( embed::InvalidStorageException,
676 				lang::IllegalArgumentException,
677 				packages::WrongPasswordException,
678 				io::IOException,
679 				embed::StorageWrappedTargetException,
680 				uno::RuntimeException )
681 {
682 	::osl::MutexGuard aGuard( m_aMutex );
683 
684 	if ( !m_pImpl )
685 		throw lang::DisposedException();
686 
687 	if ( !GetContent() )
688 		throw io::IOException(); // TODO: error handling
689 
690 	// TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
691 	INetURLObject aFileURL( m_pImpl->m_aURL );
692 	aFileURL.Append( aStreamName );
693 
694 	uno::Reference < io::XStream > xTempResult;
695 	try
696 	{
697 		uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
698 		::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
699 		uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
700 
701 		xTempResult = uno::Reference < io::XStream >(
702 					m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
703 					uno::UNO_QUERY_THROW );
704 		uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream();
705 		uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream();
706 
707 		if ( !xTempOut.is() || !xTempIn.is() )
708 			throw io::IOException();
709 
710 		::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
711 		xTempOut->closeOutput();
712 	}
713 	catch( embed::InvalidStorageException& )
714 	{
715 		throw;
716 	}
717 	catch( lang::IllegalArgumentException& )
718 	{
719 		throw;
720 	}
721 	catch( packages::WrongPasswordException& )
722 	{
723 		throw;
724 	}
725 	catch( io::IOException& )
726 	{
727 		throw;
728 	}
729 	catch( embed::StorageWrappedTargetException& )
730 	{
731 		throw;
732 	}
733 	catch( uno::RuntimeException& )
734 	{
735 		throw;
736 	}
737 	catch( uno::Exception& )
738 	{
739       	uno::Any aCaught( ::cppu::getCaughtException() );
740 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
741 												 uno::Reference< io::XInputStream >(),
742 												 aCaught );
743 	}
744 
745 	return xTempResult;
746 }
747 
748 //-----------------------------------------------
749 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
750 	const ::rtl::OUString&,
751 	const ::rtl::OUString& )
752 		throw ( embed::InvalidStorageException,
753 				lang::IllegalArgumentException,
754 				packages::NoEncryptionException,
755 				packages::WrongPasswordException,
756 				io::IOException,
757 				embed::StorageWrappedTargetException,
758 				uno::RuntimeException )
759 {
760 	throw packages::NoEncryptionException();
761 }
762 
763 //-----------------------------------------------
764 void SAL_CALL FSStorage::copyLastCommitTo(
765 			const uno::Reference< embed::XStorage >& xTargetStorage )
766 		throw ( embed::InvalidStorageException,
767 				lang::IllegalArgumentException,
768 				io::IOException,
769 				embed::StorageWrappedTargetException,
770 				uno::RuntimeException )
771 {
772 	copyToStorage( xTargetStorage );
773 }
774 
775 //-----------------------------------------------
776 void SAL_CALL FSStorage::copyStorageElementLastCommitTo(
777 			const ::rtl::OUString& aStorName,
778 			const uno::Reference< embed::XStorage >& xTargetStorage )
779 		throw ( embed::InvalidStorageException,
780 				lang::IllegalArgumentException,
781 				io::IOException,
782 				embed::StorageWrappedTargetException,
783 				uno::RuntimeException )
784 {
785 	::osl::MutexGuard aGuard( m_aMutex );
786 
787 	if ( !m_pImpl )
788 		throw lang::DisposedException();
789 
790 	uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ),
791 													uno::UNO_QUERY_THROW );
792 	xSourceStor->copyToStorage( xTargetStorage );
793 }
794 
795 //-----------------------------------------------
796 sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName )
797 		throw ( embed::InvalidStorageException,
798 				lang::IllegalArgumentException,
799 				container::NoSuchElementException,
800 				uno::RuntimeException )
801 {
802 	::osl::MutexGuard aGuard( m_aMutex );
803 
804 	if ( !m_pImpl )
805 		throw lang::DisposedException();
806 
807 	if ( !GetContent() )
808 		throw embed::InvalidStorageException(); // TODO: error handling
809 
810 	INetURLObject aURL( m_pImpl->m_aURL );
811 	aURL.Append( aElementName );
812 
813 	return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
814 }
815 
816 //-----------------------------------------------
817 sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName )
818 		throw ( embed::InvalidStorageException,
819 				lang::IllegalArgumentException,
820 				container::NoSuchElementException,
821 				uno::RuntimeException )
822 {
823 	::osl::MutexGuard aGuard( m_aMutex );
824 
825 	if ( !m_pImpl )
826 		throw lang::DisposedException();
827 
828 	if ( !GetContent() )
829 		throw embed::InvalidStorageException(); // TODO: error handling
830 
831 	INetURLObject aURL( m_pImpl->m_aURL );
832 	aURL.Append( aElementName );
833 
834 	return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
835 }
836 
837 //-----------------------------------------------
838 void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName )
839 		throw ( embed::InvalidStorageException,
840 				lang::IllegalArgumentException,
841 				container::NoSuchElementException,
842 				io::IOException,
843 				embed::StorageWrappedTargetException,
844 				uno::RuntimeException )
845 {
846 	::osl::MutexGuard aGuard( m_aMutex );
847 
848 	if ( !m_pImpl )
849 		throw lang::DisposedException();
850 
851 	if ( !GetContent() )
852 		throw io::IOException(); // TODO: error handling
853 
854 	INetURLObject aURL( m_pImpl->m_aURL );
855 	aURL.Append( aElementName );
856 
857 	if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
858 	  && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
859 		throw container::NoSuchElementException(); // TODO:
860 
861 	::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
862 }
863 
864 //-----------------------------------------------
865 void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
866 		throw ( embed::InvalidStorageException,
867 				lang::IllegalArgumentException,
868 				container::NoSuchElementException,
869 				container::ElementExistException,
870 				io::IOException,
871 				embed::StorageWrappedTargetException,
872 				uno::RuntimeException )
873 {
874 	::osl::MutexGuard aGuard( m_aMutex );
875 
876 	if ( !m_pImpl )
877 		throw lang::DisposedException();
878 
879 	if ( !GetContent() )
880 		throw io::IOException(); // TODO: error handling
881 
882 	INetURLObject aOldURL( m_pImpl->m_aURL );
883 	aOldURL.Append( aElementName );
884 
885 	INetURLObject aNewURL( m_pImpl->m_aURL );
886 	aNewURL.Append( aNewName );
887 
888 	if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) )
889 	  && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
890 		throw container::NoSuchElementException(); // TODO:
891 
892 	if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) )
893 	  || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
894 	  	throw container::ElementExistException(); // TODO:
895 
896 	try
897 	{
898 		uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
899 		::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
900 
901 		if ( !GetContent()->transferContent( aSourceContent,
902 											::ucbhelper::InsertOperation_MOVE,
903 											aNewName,
904 											ucb::NameClash::ERROR ) )
905 			throw io::IOException(); // TODO: error handling
906 	}
907 	catch( embed::InvalidStorageException& )
908 	{
909 		throw;
910 	}
911 	catch( lang::IllegalArgumentException& )
912 	{
913 		throw;
914 	}
915 	catch( container::NoSuchElementException& )
916 	{
917 		throw;
918 	}
919 	catch( container::ElementExistException& )
920 	{
921 		throw;
922 	}
923 	catch( io::IOException& )
924 	{
925 		throw;
926 	}
927 	catch( embed::StorageWrappedTargetException& )
928 	{
929 		throw;
930 	}
931 	catch( uno::RuntimeException& )
932 	{
933 		throw;
934 	}
935 	catch( uno::Exception& )
936 	{
937       	uno::Any aCaught( ::cppu::getCaughtException() );
938 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
939 												 uno::Reference< io::XInputStream >(),
940 												 aCaught );
941 	}
942 }
943 
944 //-----------------------------------------------
945 void SAL_CALL FSStorage::copyElementTo(	const ::rtl::OUString& aElementName,
946 										const uno::Reference< embed::XStorage >& xDest,
947 										const ::rtl::OUString& aNewName )
948 		throw ( embed::InvalidStorageException,
949 				lang::IllegalArgumentException,
950 				container::NoSuchElementException,
951 				container::ElementExistException,
952 				io::IOException,
953 				embed::StorageWrappedTargetException,
954 				uno::RuntimeException )
955 {
956 	::osl::MutexGuard aGuard( m_aMutex );
957 
958 	if ( !m_pImpl )
959 		throw lang::DisposedException();
960 
961 	if ( !xDest.is() )
962 		throw uno::RuntimeException();
963 
964 	if ( !GetContent() )
965 		throw io::IOException(); // TODO: error handling
966 
967 	INetURLObject aOwnURL( m_pImpl->m_aURL );
968 	aOwnURL.Append( aElementName );
969 
970 	if ( xDest->hasByName( aNewName ) )
971 	  	throw container::ElementExistException(); // TODO:
972 
973 	try
974 	{
975 		uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
976 		if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
977 		{
978 			::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
979 			uno::Reference< embed::XStorage > xDestSubStor(
980 									xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ),
981 									uno::UNO_QUERY_THROW );
982 
983 			CopyContentToStorage_Impl( &aSourceContent, xDestSubStor );
984 		}
985 		else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
986 		{
987 			CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName );
988 		}
989 		else
990 			throw container::NoSuchElementException(); // TODO:
991 	}
992 	catch( embed::InvalidStorageException& )
993 	{
994 		throw;
995 	}
996 	catch( lang::IllegalArgumentException& )
997 	{
998 		throw;
999 	}
1000 	catch( container::NoSuchElementException& )
1001 	{
1002 		throw;
1003 	}
1004 	catch( container::ElementExistException& )
1005 	{
1006 		throw;
1007 	}
1008 	catch( embed::StorageWrappedTargetException& )
1009 	{
1010 		throw;
1011 	}
1012 	catch( io::IOException& )
1013 	{
1014 		throw;
1015 	}
1016 	catch( uno::RuntimeException& )
1017 	{
1018 		throw;
1019 	}
1020 	catch( uno::Exception& )
1021 	{
1022       	uno::Any aCaught( ::cppu::getCaughtException() );
1023 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1024 												 uno::Reference< io::XInputStream >(),
1025 												 aCaught );
1026 	}
1027 }
1028 
1029 //-----------------------------------------------
1030 void SAL_CALL FSStorage::moveElementTo(	const ::rtl::OUString& aElementName,
1031 										const uno::Reference< embed::XStorage >& xDest,
1032 										const ::rtl::OUString& aNewName )
1033 		throw ( embed::InvalidStorageException,
1034 				lang::IllegalArgumentException,
1035 				container::NoSuchElementException,
1036 				container::ElementExistException,
1037 				io::IOException,
1038 				embed::StorageWrappedTargetException,
1039 				uno::RuntimeException )
1040 {
1041 	::osl::MutexGuard aGuard( m_aMutex );
1042 	copyElementTo( aElementName, xDest, aNewName );
1043 
1044 	INetURLObject aOwnURL( m_pImpl->m_aURL );
1045 	aOwnURL.Append( aElementName );
1046 	if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1047 		throw io::IOException(); // TODO: error handling
1048 }
1049 
1050 //____________________________________________________________________________________________________
1051 //	XNameAccess
1052 //____________________________________________________________________________________________________
1053 
1054 //-----------------------------------------------
1055 uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName )
1056 		throw ( container::NoSuchElementException,
1057 				lang::WrappedTargetException,
1058 				uno::RuntimeException )
1059 {
1060 	::osl::MutexGuard aGuard( m_aMutex );
1061 
1062 	if ( !m_pImpl )
1063 		throw lang::DisposedException();
1064 
1065 	if ( !GetContent() )
1066 		throw io::IOException(); // TODO: error handling
1067 
1068 	if ( !aName.getLength() )
1069 		throw lang::IllegalArgumentException();
1070 
1071 	INetURLObject aURL( m_pImpl->m_aURL );
1072 	aURL.Append( aName );
1073 
1074 	uno::Any aResult;
1075 	try
1076 	{
1077 		if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1078 		{
1079 			aResult <<= openStorageElement( aName, embed::ElementModes::READ );
1080 		}
1081 		else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1082 		{
1083 			aResult <<= openStreamElement( aName, embed::ElementModes::READ );
1084 		}
1085 		else
1086 			throw container::NoSuchElementException(); // TODO:
1087 	}
1088 	catch( container::NoSuchElementException& )
1089 	{
1090 		throw;
1091 	}
1092 	catch( lang::WrappedTargetException& )
1093 	{
1094 		throw;
1095 	}
1096 	catch( uno::RuntimeException& )
1097 	{
1098 		throw;
1099 	}
1100 	catch ( uno::Exception& )
1101 	{
1102    		uno::Any aCaught( ::cppu::getCaughtException() );
1103 		throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ),
1104 											uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1105 																				uno::UNO_QUERY ),
1106 											aCaught );
1107 	}
1108 
1109 	return aResult;
1110 }
1111 
1112 
1113 //-----------------------------------------------
1114 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames()
1115 		throw ( uno::RuntimeException )
1116 {
1117 	::osl::MutexGuard aGuard( m_aMutex );
1118 
1119 	if ( !m_pImpl )
1120 		throw lang::DisposedException();
1121 
1122 	if ( !GetContent() )
1123 		throw io::IOException(); // TODO: error handling
1124 
1125 	uno::Sequence< ::rtl::OUString > aProps( 1 );
1126 	::rtl::OUString* pProps = aProps.getArray();
1127 	pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
1128 	::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1129 
1130 	uno::Sequence< ::rtl::OUString > aResult;
1131 	sal_Int32 nSize = 0;
1132 
1133 	try
1134 	{
1135 		uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1136 		uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
1137 		uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
1138 		if ( xResultSet.is() )
1139 		{
1140 			// go through the list
1141 			while ( xResultSet->next() )
1142 			{
1143 				::rtl::OUString aName( xRow->getString( 1 ) );
1144 				aResult.realloc( ++nSize );
1145 				aResult[nSize-1] = aName;
1146 			}
1147 		}
1148 	}
1149 	catch( ucb::InteractiveIOException& r )
1150     {
1151         if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
1152 			OSL_ENSURE( sal_False, "The folder does not exist!\n" );
1153 		else
1154 		{
1155 	   		uno::Any aCaught( ::cppu::getCaughtException() );
1156 			throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1157 											uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1158 																				uno::UNO_QUERY ),
1159 											aCaught );
1160 		}
1161     }
1162 	catch( uno::RuntimeException& )
1163 	{
1164 		throw;
1165 	}
1166 	catch ( uno::Exception& )
1167 	{
1168    		uno::Any aCaught( ::cppu::getCaughtException() );
1169 		throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1170 											uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1171 																				uno::UNO_QUERY ),
1172 											aCaught );
1173 	}
1174 
1175 	return aResult;
1176 }
1177 
1178 
1179 //-----------------------------------------------
1180 sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName )
1181 		throw ( uno::RuntimeException )
1182 {
1183 	::osl::MutexGuard aGuard( m_aMutex );
1184 
1185 	if ( !m_pImpl )
1186 		throw lang::DisposedException();
1187 
1188 	try
1189 	{
1190 		if ( !GetContent() )
1191 			throw io::IOException(); // TODO: error handling
1192 
1193 		if ( !aName.getLength() )
1194 			throw lang::IllegalArgumentException();
1195 	}
1196 	catch( uno::RuntimeException& )
1197 	{
1198 		throw;
1199 	}
1200 	catch ( uno::Exception& )
1201 	{
1202    		uno::Any aCaught( ::cppu::getCaughtException() );
1203 		throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1204 											uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1205 																				uno::UNO_QUERY ),
1206 											aCaught );
1207 	}
1208 
1209 	INetURLObject aURL( m_pImpl->m_aURL );
1210 	aURL.Append( aName );
1211 
1212 	return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
1213 	  || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1214 }
1215 
1216 //-----------------------------------------------
1217 uno::Type SAL_CALL FSStorage::getElementType()
1218 		throw ( uno::RuntimeException )
1219 {
1220 	::osl::MutexGuard aGuard( m_aMutex );
1221 
1222 	if ( !m_pImpl )
1223 		throw lang::DisposedException();
1224 
1225 	// it is a multitype container
1226 	return uno::Type();
1227 }
1228 
1229 //-----------------------------------------------
1230 sal_Bool SAL_CALL FSStorage::hasElements()
1231 		throw ( uno::RuntimeException )
1232 {
1233 	::osl::MutexGuard aGuard( m_aMutex );
1234 
1235 	if ( !m_pImpl )
1236 		throw lang::DisposedException();
1237 
1238 	if ( !GetContent() )
1239 		throw io::IOException(); // TODO: error handling
1240 
1241 	uno::Sequence< ::rtl::OUString > aProps( 1 );
1242 	aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
1243 	::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1244 
1245 	try
1246 	{
1247 		uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1248 		return ( xResultSet.is() && xResultSet->next() );
1249 	}
1250 	catch( uno::Exception& )
1251 	{
1252 		throw uno::RuntimeException();
1253 	}
1254 }
1255 
1256 
1257 //____________________________________________________________________________________________________
1258 //	XDisposable
1259 //____________________________________________________________________________________________________
1260 
1261 //-----------------------------------------------
1262 void SAL_CALL FSStorage::dispose()
1263 		throw ( uno::RuntimeException )
1264 {
1265 	::osl::MutexGuard aGuard( m_aMutex );
1266 
1267 	if ( !m_pImpl )
1268 		throw lang::DisposedException();
1269 
1270 	if ( m_pImpl->m_pListenersContainer )
1271 	{
1272    		lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1273 		m_pImpl->m_pListenersContainer->disposeAndClear( aSource );
1274 	}
1275 
1276 	delete m_pImpl;
1277 	m_pImpl = NULL;
1278 }
1279 
1280 //-----------------------------------------------
1281 void SAL_CALL FSStorage::addEventListener(
1282 			const uno::Reference< lang::XEventListener >& xListener )
1283 		throw ( uno::RuntimeException )
1284 {
1285 	::osl::MutexGuard aGuard( m_aMutex );
1286 
1287 	if ( !m_pImpl )
1288 		throw lang::DisposedException();
1289 
1290 	if ( !m_pImpl->m_pListenersContainer )
1291 		m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
1292 
1293 	m_pImpl->m_pListenersContainer->addInterface( xListener );
1294 }
1295 
1296 //-----------------------------------------------
1297 void SAL_CALL FSStorage::removeEventListener(
1298 			const uno::Reference< lang::XEventListener >& xListener )
1299 		throw ( uno::RuntimeException )
1300 {
1301 	::osl::MutexGuard aGuard( m_aMutex );
1302 
1303 	if ( !m_pImpl )
1304 		throw lang::DisposedException();
1305 
1306 	if ( m_pImpl->m_pListenersContainer )
1307 		m_pImpl->m_pListenersContainer->removeInterface( xListener );
1308 }
1309 
1310 //____________________________________________________________________________________________________
1311 //	XPropertySet
1312 //____________________________________________________________________________________________________
1313 
1314 //-----------------------------------------------
1315 uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
1316 		throw ( uno::RuntimeException )
1317 {
1318 	::osl::MutexGuard aGuard( m_aMutex );
1319 
1320 	if ( !m_pImpl )
1321 		throw lang::DisposedException();
1322 
1323 	//TODO:
1324 	return uno::Reference< beans::XPropertySetInfo >();
1325 }
1326 
1327 
1328 //-----------------------------------------------
1329 void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
1330 		throw ( beans::UnknownPropertyException,
1331 				beans::PropertyVetoException,
1332 				lang::IllegalArgumentException,
1333 				lang::WrappedTargetException,
1334 				uno::RuntimeException )
1335 {
1336 	::osl::MutexGuard aGuard( m_aMutex );
1337 
1338 	if ( !m_pImpl )
1339 		throw lang::DisposedException();
1340 
1341 	if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) )
1342 		throw beans::PropertyVetoException(); // TODO
1343 	else
1344 		throw beans::UnknownPropertyException(); // TODO
1345 }
1346 
1347 
1348 //-----------------------------------------------
1349 uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
1350 		throw ( beans::UnknownPropertyException,
1351 				lang::WrappedTargetException,
1352 				uno::RuntimeException )
1353 {
1354 	::osl::MutexGuard aGuard( m_aMutex );
1355 
1356 	if ( !m_pImpl )
1357 		throw lang::DisposedException();
1358 
1359 	if ( aPropertyName.equalsAscii( "URL" ) )
1360 		return uno::makeAny( m_pImpl->m_aURL );
1361 	else if ( aPropertyName.equalsAscii( "OpenMode" ) )
1362 		return uno::makeAny( m_pImpl->m_nMode );
1363 
1364 	throw beans::UnknownPropertyException(); // TODO
1365 }
1366 
1367 
1368 //-----------------------------------------------
1369 void SAL_CALL FSStorage::addPropertyChangeListener(
1370 			const ::rtl::OUString& /*aPropertyName*/,
1371 			const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
1372 		throw ( beans::UnknownPropertyException,
1373 				lang::WrappedTargetException,
1374 				uno::RuntimeException )
1375 {
1376 	::osl::MutexGuard aGuard( m_aMutex );
1377 
1378 	if ( !m_pImpl )
1379 		throw lang::DisposedException();
1380 
1381 	//TODO:
1382 }
1383 
1384 
1385 //-----------------------------------------------
1386 void SAL_CALL FSStorage::removePropertyChangeListener(
1387 			const ::rtl::OUString& /*aPropertyName*/,
1388 			const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
1389 		throw ( beans::UnknownPropertyException,
1390 				lang::WrappedTargetException,
1391 				uno::RuntimeException )
1392 {
1393 	::osl::MutexGuard aGuard( m_aMutex );
1394 
1395 	if ( !m_pImpl )
1396 		throw lang::DisposedException();
1397 
1398 	//TODO:
1399 }
1400 
1401 
1402 //-----------------------------------------------
1403 void SAL_CALL FSStorage::addVetoableChangeListener(
1404 			const ::rtl::OUString& /*PropertyName*/,
1405 			const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1406 		throw ( beans::UnknownPropertyException,
1407 				lang::WrappedTargetException,
1408 				uno::RuntimeException )
1409 {
1410 	::osl::MutexGuard aGuard( m_aMutex );
1411 
1412 	if ( !m_pImpl )
1413 		throw lang::DisposedException();
1414 
1415 	//TODO:
1416 }
1417 
1418 
1419 //-----------------------------------------------
1420 void SAL_CALL FSStorage::removeVetoableChangeListener(
1421 			const ::rtl::OUString& /*PropertyName*/,
1422 			const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1423 		throw ( beans::UnknownPropertyException,
1424 				lang::WrappedTargetException,
1425 				uno::RuntimeException )
1426 {
1427 	::osl::MutexGuard aGuard( m_aMutex );
1428 
1429 	if ( !m_pImpl )
1430 		throw lang::DisposedException();
1431 
1432 	//TODO:
1433 }
1434 
1435 //____________________________________________________________________________________________________
1436 //	XHierarchicalStorageAccess
1437 //____________________________________________________________________________________________________
1438 //-----------------------------------------------
1439 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode )
1440 		throw ( embed::InvalidStorageException,
1441 				lang::IllegalArgumentException,
1442 				packages::WrongPasswordException,
1443 				io::IOException,
1444 				embed::StorageWrappedTargetException,
1445 				uno::RuntimeException )
1446 {
1447 	::osl::MutexGuard aGuard( m_aMutex );
1448 
1449 	if ( !m_pImpl )
1450 		throw lang::DisposedException();
1451 
1452 	if ( sStreamPath.toChar() == '/' )
1453 		throw lang::IllegalArgumentException();
1454 
1455 	if ( !GetContent() )
1456 		throw io::IOException(); // TODO: error handling
1457 
1458 	INetURLObject aBaseURL( m_pImpl->m_aURL );
1459 	if ( !aBaseURL.setFinalSlash() )
1460 		throw uno::RuntimeException();
1461 
1462 	INetURLObject aFileURL = INetURLObject::GetAbsURL(
1463 				aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1464 				sStreamPath );
1465 
1466 	if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1467 		throw io::IOException();
1468 
1469 	if ( ( nOpenMode & embed::ElementModes::NOCREATE )
1470 	  && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1471 		throw io::IOException(); // TODO:
1472 
1473 	uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
1474 	uno::Reference< io::XStream > xResult;
1475 	try
1476 	{
1477 		if ( nOpenMode & embed::ElementModes::WRITE )
1478 		{
1479 			if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1480 			{
1481 				uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
1482 					m_pImpl->m_xFactory->createInstance(
1483 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
1484 					uno::UNO_QUERY_THROW );
1485 				uno::Reference< io::XStream > xStream =
1486 					xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
1487 
1488 				xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1489 			}
1490 			else
1491 			{
1492 				// TODO: test whether it really works for http and fwp
1493 				SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1494 																	  	STREAM_STD_WRITE );
1495 				if ( pStream )
1496 				{
1497 					if ( !pStream->GetError() )
1498 					{
1499 						uno::Reference< io::XStream > xStream =
1500 							uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
1501 						xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1502 					}
1503 					else
1504 						delete pStream;
1505 				}
1506 			}
1507 
1508 			if ( !xResult.is() )
1509 				throw io::IOException();
1510 
1511 			if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
1512 			{
1513 				uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
1514 				xTrunc->truncate();
1515 			}
1516 		}
1517 		else
1518 		{
1519 			if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
1520 		  	|| !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1521 				throw io::IOException(); // TODO: access denied
1522 
1523 			::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
1524 			uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
1525 			xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
1526 		}
1527 	}
1528 	catch( embed::InvalidStorageException& )
1529 	{
1530 		throw;
1531 	}
1532 	catch( lang::IllegalArgumentException& )
1533 	{
1534 		throw;
1535 	}
1536 	catch( packages::WrongPasswordException& )
1537 	{
1538 		throw;
1539 	}
1540 	catch( embed::StorageWrappedTargetException& )
1541 	{
1542 		throw;
1543 	}
1544 	catch( io::IOException& )
1545 	{
1546 		throw;
1547 	}
1548 	catch( uno::RuntimeException& )
1549 	{
1550 		throw;
1551 	}
1552 	catch( uno::Exception& )
1553 	{
1554       	uno::Any aCaught( ::cppu::getCaughtException() );
1555 		throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1556 												 uno::Reference< io::XInputStream >(),
1557 												 aCaught );
1558 	}
1559 
1560 	return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW );
1561 }
1562 
1563 //-----------------------------------------------
1564 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ )
1565 		throw ( embed::InvalidStorageException,
1566 				lang::IllegalArgumentException,
1567 				packages::NoEncryptionException,
1568 				packages::WrongPasswordException,
1569 				io::IOException,
1570 				embed::StorageWrappedTargetException,
1571 				uno::RuntimeException )
1572 {
1573 	throw packages::NoEncryptionException();
1574 }
1575 
1576 //-----------------------------------------------
1577 void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath )
1578 		throw ( embed::InvalidStorageException,
1579 				lang::IllegalArgumentException,
1580 				container::NoSuchElementException,
1581 				io::IOException,
1582 				embed::StorageWrappedTargetException,
1583 				uno::RuntimeException )
1584 {
1585 	::osl::MutexGuard aGuard( m_aMutex );
1586 
1587 	if ( !m_pImpl )
1588 		throw lang::DisposedException();
1589 
1590 	if ( !GetContent() )
1591 		throw io::IOException(); // TODO: error handling
1592 
1593 	// TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1594 	INetURLObject aBaseURL( m_pImpl->m_aURL );
1595 	if ( !aBaseURL.setFinalSlash() )
1596 		throw uno::RuntimeException();
1597 
1598 	INetURLObject aFileURL = INetURLObject::GetAbsURL(
1599 				aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1600 				sStreamPath );
1601 
1602 	if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1603 	{
1604 		if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1605 			throw lang::IllegalArgumentException();
1606 		else
1607 			throw container::NoSuchElementException(); // TODO:
1608 	}
1609 
1610 	if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1611 		throw io::IOException(); // TODO: error handling
1612 }
1613 
1614 
1615