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