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 {
316 uno::Any aReturn;
317 aReturn <<= ::cppu::queryInterface
318 ( rType
319 , static_cast<lang::XTypeProvider*> ( this )
320 , static_cast<embed::XStorage*> ( this )
321 , static_cast<embed::XHierarchicalStorageAccess*> ( this )
322 , static_cast<container::XNameAccess*> ( this )
323 , static_cast<container::XElementAccess*> ( this )
324 , static_cast<lang::XComponent*> ( this )
325 , static_cast<beans::XPropertySet*> ( this ) );
326
327 if ( aReturn.hasValue() == sal_True )
328 return aReturn ;
329
330 return OWeakObject::queryInterface( rType );
331 }
332
333 //-----------------------------------------------
acquire()334 void SAL_CALL FSStorage::acquire() throw()
335 {
336 OWeakObject::acquire();
337 }
338
339 //-----------------------------------------------
release()340 void SAL_CALL FSStorage::release() throw()
341 {
342 OWeakObject::release();
343 }
344
345 //____________________________________________________________________________________________________
346 // XTypeProvider
347 //____________________________________________________________________________________________________
348
349 //-----------------------------------------------
getTypes()350 uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes()
351 {
352 if ( m_pImpl->m_pTypeCollection == NULL )
353 {
354 ::osl::MutexGuard aGuard( m_aMutex );
355
356 if ( m_pImpl->m_pTypeCollection == NULL )
357 {
358 m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection
359 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
360 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
361 , ::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL )
362 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
363 }
364 }
365
366 return m_pImpl->m_pTypeCollection->getTypes() ;
367 }
368
369 //-----------------------------------------------
getImplementationId()370 uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
371 {
372 static ::cppu::OImplementationId* pID = NULL ;
373
374 if ( pID == NULL )
375 {
376 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
377
378 if ( pID == NULL )
379 {
380 static ::cppu::OImplementationId aID( sal_False ) ;
381 pID = &aID ;
382 }
383 }
384
385 return pID->getImplementationId() ;
386
387 }
388
389 //____________________________________________________________________________________________________
390 // XStorage
391 //____________________________________________________________________________________________________
392
393 //-----------------------------------------------
copyToStorage(const uno::Reference<embed::XStorage> & xDest)394 void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
395 {
396 ::osl::MutexGuard aGuard( m_aMutex );
397
398 if ( !m_pImpl )
399 throw lang::DisposedException();
400
401 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
402 throw lang::IllegalArgumentException(); // TODO:
403
404 if ( !GetContent() )
405 throw io::IOException(); // TODO: error handling
406
407 try
408 {
409 CopyContentToStorage_Impl( GetContent(), xDest );
410 }
411 catch( embed::InvalidStorageException& )
412 {
413 throw;
414 }
415 catch( lang::IllegalArgumentException& )
416 {
417 throw;
418 }
419 catch( embed::StorageWrappedTargetException& )
420 {
421 throw;
422 }
423 catch( io::IOException& )
424 {
425 throw;
426 }
427 catch( uno::RuntimeException& )
428 {
429 throw;
430 }
431 catch( uno::Exception& )
432 {
433 uno::Any aCaught( ::cppu::getCaughtException() );
434 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
435 uno::Reference< io::XInputStream >(),
436 aCaught );
437 }
438 }
439
440 //-----------------------------------------------
openStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode)441 uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement(
442 const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
443 {
444 ::osl::MutexGuard aGuard( m_aMutex );
445
446 if ( !m_pImpl )
447 throw lang::DisposedException();
448
449 if ( !GetContent() )
450 throw io::IOException(); // TODO: error handling
451
452 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
453 INetURLObject aFileURL( m_pImpl->m_aURL );
454 aFileURL.Append( aStreamName );
455
456 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
457 throw io::IOException();
458
459 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
460 && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
461 throw io::IOException(); // TODO:
462
463 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
464 uno::Reference< io::XStream > xResult;
465 try
466 {
467 if ( nOpenMode & embed::ElementModes::WRITE )
468 {
469 if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
470 {
471 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
472 m_pImpl->m_xFactory->createInstance(
473 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
474 uno::UNO_QUERY_THROW );
475 xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
476 }
477 else
478 {
479 // TODO: test whether it really works for http and fwp
480 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
481 STREAM_STD_WRITE );
482 if ( pStream )
483 {
484 if ( !pStream->GetError() )
485 xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
486 else
487 delete pStream;
488 }
489 }
490
491 if ( !xResult.is() )
492 throw io::IOException();
493
494 if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
495 {
496 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
497 xTrunc->truncate();
498 }
499 }
500 else
501 {
502 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
503 || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
504 throw io::IOException(); // TODO: access denied
505
506 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
507 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
508 xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
509 }
510 }
511 catch( embed::InvalidStorageException& )
512 {
513 throw;
514 }
515 catch( lang::IllegalArgumentException& )
516 {
517 throw;
518 }
519 catch( packages::WrongPasswordException& )
520 {
521 throw;
522 }
523 catch( embed::StorageWrappedTargetException& )
524 {
525 throw;
526 }
527 catch( io::IOException& )
528 {
529 throw;
530 }
531 catch( uno::RuntimeException& )
532 {
533 throw;
534 }
535 catch( uno::Exception& )
536 {
537 uno::Any aCaught( ::cppu::getCaughtException() );
538 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
539 uno::Reference< io::XInputStream >(),
540 aCaught );
541 }
542
543 return xResult;
544 }
545
546 //-----------------------------------------------
openEncryptedStreamElement(const::rtl::OUString &,sal_Int32,const::rtl::OUString &)547 uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement(
548 const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& )
549 {
550 throw packages::NoEncryptionException();
551 }
552
553 //-----------------------------------------------
openStorageElement(const::rtl::OUString & aStorName,sal_Int32 nStorageMode)554 uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement(
555 const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
556 {
557 ::osl::MutexGuard aGuard( m_aMutex );
558
559 if ( !m_pImpl )
560 throw lang::DisposedException();
561
562 if ( !GetContent() )
563 throw io::IOException(); // TODO: error handling
564
565 if ( ( nStorageMode & embed::ElementModes::WRITE )
566 && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) )
567 throw io::IOException(); // TODO: error handling
568
569 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
570 INetURLObject aFolderURL( m_pImpl->m_aURL );
571 aFolderURL.Append( aStorName );
572
573 sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
574 if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
575 throw io::IOException(); // TODO:
576
577 if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists )
578 throw io::IOException(); // TODO:
579
580 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
581 uno::Reference< embed::XStorage > xResult;
582 try
583 {
584 if ( nStorageMode & embed::ElementModes::WRITE )
585 {
586 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists )
587 {
588 ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
589 bFolderExists =
590 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
591 }
592 else if ( !bFolderExists )
593 {
594 bFolderExists =
595 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
596 }
597 }
598 else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
599 throw io::IOException(); // TODO: access denied
600
601 if ( !bFolderExists )
602 throw io::IOException(); // there is no such folder
603
604 ::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
605 xResult = uno::Reference< embed::XStorage >(
606 static_cast< OWeakObject* >( new FSStorage( aResultContent,
607 nStorageMode,
608 uno::Sequence< beans::PropertyValue >(),
609 m_pImpl->m_xFactory ) ),
610 uno::UNO_QUERY );
611 }
612 catch( embed::InvalidStorageException& )
613 {
614 throw;
615 }
616 catch( lang::IllegalArgumentException& )
617 {
618 throw;
619 }
620 catch( embed::StorageWrappedTargetException& )
621 {
622 throw;
623 }
624 catch( io::IOException& )
625 {
626 throw;
627 }
628 catch( uno::RuntimeException& )
629 {
630 throw;
631 }
632 catch( uno::Exception& )
633 {
634 uno::Any aCaught( ::cppu::getCaughtException() );
635 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
636 uno::Reference< io::XInputStream >(),
637 aCaught );
638 }
639
640 return xResult;
641 }
642
643 //-----------------------------------------------
cloneStreamElement(const::rtl::OUString & aStreamName)644 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
645 {
646 ::osl::MutexGuard aGuard( m_aMutex );
647
648 if ( !m_pImpl )
649 throw lang::DisposedException();
650
651 if ( !GetContent() )
652 throw io::IOException(); // TODO: error handling
653
654 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
655 INetURLObject aFileURL( m_pImpl->m_aURL );
656 aFileURL.Append( aStreamName );
657
658 uno::Reference < io::XStream > xTempResult;
659 try
660 {
661 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
662 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
663 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
664
665 xTempResult = uno::Reference < io::XStream >(
666 m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
667 uno::UNO_QUERY_THROW );
668 uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream();
669 uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream();
670
671 if ( !xTempOut.is() || !xTempIn.is() )
672 throw io::IOException();
673
674 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
675 xTempOut->closeOutput();
676 }
677 catch( embed::InvalidStorageException& )
678 {
679 throw;
680 }
681 catch( lang::IllegalArgumentException& )
682 {
683 throw;
684 }
685 catch( packages::WrongPasswordException& )
686 {
687 throw;
688 }
689 catch( io::IOException& )
690 {
691 throw;
692 }
693 catch( embed::StorageWrappedTargetException& )
694 {
695 throw;
696 }
697 catch( uno::RuntimeException& )
698 {
699 throw;
700 }
701 catch( uno::Exception& )
702 {
703 uno::Any aCaught( ::cppu::getCaughtException() );
704 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
705 uno::Reference< io::XInputStream >(),
706 aCaught );
707 }
708
709 return xTempResult;
710 }
711
712 //-----------------------------------------------
cloneEncryptedStreamElement(const::rtl::OUString &,const::rtl::OUString &)713 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
714 const ::rtl::OUString&,
715 const ::rtl::OUString& )
716 {
717 throw packages::NoEncryptionException();
718 }
719
720 //-----------------------------------------------
copyLastCommitTo(const uno::Reference<embed::XStorage> & xTargetStorage)721 void SAL_CALL FSStorage::copyLastCommitTo(
722 const uno::Reference< embed::XStorage >& xTargetStorage )
723 {
724 copyToStorage( xTargetStorage );
725 }
726
727 //-----------------------------------------------
copyStorageElementLastCommitTo(const::rtl::OUString & aStorName,const uno::Reference<embed::XStorage> & xTargetStorage)728 void SAL_CALL FSStorage::copyStorageElementLastCommitTo(
729 const ::rtl::OUString& aStorName,
730 const uno::Reference< embed::XStorage >& xTargetStorage )
731 {
732 ::osl::MutexGuard aGuard( m_aMutex );
733
734 if ( !m_pImpl )
735 throw lang::DisposedException();
736
737 uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ),
738 uno::UNO_QUERY_THROW );
739 xSourceStor->copyToStorage( xTargetStorage );
740 }
741
742 //-----------------------------------------------
isStreamElement(const::rtl::OUString & aElementName)743 sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName )
744 {
745 ::osl::MutexGuard aGuard( m_aMutex );
746
747 if ( !m_pImpl )
748 throw lang::DisposedException();
749
750 if ( !GetContent() )
751 throw embed::InvalidStorageException(); // TODO: error handling
752
753 INetURLObject aURL( m_pImpl->m_aURL );
754 aURL.Append( aElementName );
755
756 return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
757 }
758
759 //-----------------------------------------------
isStorageElement(const::rtl::OUString & aElementName)760 sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName )
761 {
762 ::osl::MutexGuard aGuard( m_aMutex );
763
764 if ( !m_pImpl )
765 throw lang::DisposedException();
766
767 if ( !GetContent() )
768 throw embed::InvalidStorageException(); // TODO: error handling
769
770 INetURLObject aURL( m_pImpl->m_aURL );
771 aURL.Append( aElementName );
772
773 return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
774 }
775
776 //-----------------------------------------------
removeElement(const::rtl::OUString & aElementName)777 void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName )
778 {
779 ::osl::MutexGuard aGuard( m_aMutex );
780
781 if ( !m_pImpl )
782 throw lang::DisposedException();
783
784 if ( !GetContent() )
785 throw io::IOException(); // TODO: error handling
786
787 INetURLObject aURL( m_pImpl->m_aURL );
788 aURL.Append( aElementName );
789
790 if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
791 && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
792 throw container::NoSuchElementException(); // TODO:
793
794 ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
795 }
796
797 //-----------------------------------------------
renameElement(const::rtl::OUString & aElementName,const::rtl::OUString & aNewName)798 void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
799 {
800 ::osl::MutexGuard aGuard( m_aMutex );
801
802 if ( !m_pImpl )
803 throw lang::DisposedException();
804
805 if ( !GetContent() )
806 throw io::IOException(); // TODO: error handling
807
808 INetURLObject aOldURL( m_pImpl->m_aURL );
809 aOldURL.Append( aElementName );
810
811 INetURLObject aNewURL( m_pImpl->m_aURL );
812 aNewURL.Append( aNewName );
813
814 if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) )
815 && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
816 throw container::NoSuchElementException(); // TODO:
817
818 if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) )
819 || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
820 throw container::ElementExistException(); // TODO:
821
822 try
823 {
824 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
825 ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
826
827 if ( !GetContent()->transferContent( aSourceContent,
828 ::ucbhelper::InsertOperation_MOVE,
829 aNewName,
830 ucb::NameClash::ERROR ) )
831 throw io::IOException(); // TODO: error handling
832 }
833 catch( embed::InvalidStorageException& )
834 {
835 throw;
836 }
837 catch( lang::IllegalArgumentException& )
838 {
839 throw;
840 }
841 catch( container::NoSuchElementException& )
842 {
843 throw;
844 }
845 catch( container::ElementExistException& )
846 {
847 throw;
848 }
849 catch( io::IOException& )
850 {
851 throw;
852 }
853 catch( embed::StorageWrappedTargetException& )
854 {
855 throw;
856 }
857 catch( uno::RuntimeException& )
858 {
859 throw;
860 }
861 catch( uno::Exception& )
862 {
863 uno::Any aCaught( ::cppu::getCaughtException() );
864 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
865 uno::Reference< io::XInputStream >(),
866 aCaught );
867 }
868 }
869
870 //-----------------------------------------------
copyElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)871 void SAL_CALL FSStorage::copyElementTo( const ::rtl::OUString& aElementName,
872 const uno::Reference< embed::XStorage >& xDest,
873 const ::rtl::OUString& aNewName )
874 {
875 ::osl::MutexGuard aGuard( m_aMutex );
876
877 if ( !m_pImpl )
878 throw lang::DisposedException();
879
880 if ( !xDest.is() )
881 throw uno::RuntimeException();
882
883 if ( !GetContent() )
884 throw io::IOException(); // TODO: error handling
885
886 INetURLObject aOwnURL( m_pImpl->m_aURL );
887 aOwnURL.Append( aElementName );
888
889 if ( xDest->hasByName( aNewName ) )
890 throw container::ElementExistException(); // TODO:
891
892 try
893 {
894 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
895 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
896 {
897 ::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
898 uno::Reference< embed::XStorage > xDestSubStor(
899 xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ),
900 uno::UNO_QUERY_THROW );
901
902 CopyContentToStorage_Impl( &aSourceContent, xDestSubStor );
903 }
904 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
905 {
906 CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName );
907 }
908 else
909 throw container::NoSuchElementException(); // TODO:
910 }
911 catch( embed::InvalidStorageException& )
912 {
913 throw;
914 }
915 catch( lang::IllegalArgumentException& )
916 {
917 throw;
918 }
919 catch( container::NoSuchElementException& )
920 {
921 throw;
922 }
923 catch( container::ElementExistException& )
924 {
925 throw;
926 }
927 catch( embed::StorageWrappedTargetException& )
928 {
929 throw;
930 }
931 catch( io::IOException& )
932 {
933 throw;
934 }
935 catch( uno::RuntimeException& )
936 {
937 throw;
938 }
939 catch( uno::Exception& )
940 {
941 uno::Any aCaught( ::cppu::getCaughtException() );
942 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
943 uno::Reference< io::XInputStream >(),
944 aCaught );
945 }
946 }
947
948 //-----------------------------------------------
moveElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)949 void SAL_CALL FSStorage::moveElementTo( const ::rtl::OUString& aElementName,
950 const uno::Reference< embed::XStorage >& xDest,
951 const ::rtl::OUString& aNewName )
952 {
953 ::osl::MutexGuard aGuard( m_aMutex );
954 copyElementTo( aElementName, xDest, aNewName );
955
956 INetURLObject aOwnURL( m_pImpl->m_aURL );
957 aOwnURL.Append( aElementName );
958 if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
959 throw io::IOException(); // TODO: error handling
960 }
961
962 //____________________________________________________________________________________________________
963 // XNameAccess
964 //____________________________________________________________________________________________________
965
966 //-----------------------------------------------
getByName(const::rtl::OUString & aName)967 uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName )
968 {
969 ::osl::MutexGuard aGuard( m_aMutex );
970
971 if ( !m_pImpl )
972 throw lang::DisposedException();
973
974 if ( !GetContent() )
975 throw io::IOException(); // TODO: error handling
976
977 if ( !aName.getLength() )
978 throw lang::IllegalArgumentException();
979
980 INetURLObject aURL( m_pImpl->m_aURL );
981 aURL.Append( aName );
982
983 uno::Any aResult;
984 try
985 {
986 if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
987 {
988 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
989 }
990 else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
991 {
992 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
993 }
994 else
995 throw container::NoSuchElementException(); // TODO:
996 }
997 catch( container::NoSuchElementException& )
998 {
999 throw;
1000 }
1001 catch( lang::WrappedTargetException& )
1002 {
1003 throw;
1004 }
1005 catch( uno::RuntimeException& )
1006 {
1007 throw;
1008 }
1009 catch ( uno::Exception& )
1010 {
1011 uno::Any aCaught( ::cppu::getCaughtException() );
1012 throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ),
1013 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1014 uno::UNO_QUERY ),
1015 aCaught );
1016 }
1017
1018 return aResult;
1019 }
1020
1021
1022 //-----------------------------------------------
getElementNames()1023 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames()
1024 {
1025 ::osl::MutexGuard aGuard( m_aMutex );
1026
1027 if ( !m_pImpl )
1028 throw lang::DisposedException();
1029
1030 if ( !GetContent() )
1031 throw io::IOException(); // TODO: error handling
1032
1033 uno::Sequence< ::rtl::OUString > aProps( 1 );
1034 ::rtl::OUString* pProps = aProps.getArray();
1035 pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
1036 ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1037
1038 uno::Sequence< ::rtl::OUString > aResult;
1039 sal_Int32 nSize = 0;
1040
1041 try
1042 {
1043 uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1044 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
1045 uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
1046 if ( xResultSet.is() )
1047 {
1048 // go through the list
1049 while ( xResultSet->next() )
1050 {
1051 ::rtl::OUString aName( xRow->getString( 1 ) );
1052 aResult.realloc( ++nSize );
1053 aResult[nSize-1] = aName;
1054 }
1055 }
1056 }
1057 catch( ucb::InteractiveIOException& r )
1058 {
1059 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
1060 OSL_ENSURE( sal_False, "The folder does not exist!\n" );
1061 else
1062 {
1063 uno::Any aCaught( ::cppu::getCaughtException() );
1064 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1065 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1066 uno::UNO_QUERY ),
1067 aCaught );
1068 }
1069 }
1070 catch( uno::RuntimeException& )
1071 {
1072 throw;
1073 }
1074 catch ( uno::Exception& )
1075 {
1076 uno::Any aCaught( ::cppu::getCaughtException() );
1077 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1078 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1079 uno::UNO_QUERY ),
1080 aCaught );
1081 }
1082
1083 return aResult;
1084 }
1085
1086
1087 //-----------------------------------------------
hasByName(const::rtl::OUString & aName)1088 sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName )
1089 {
1090 ::osl::MutexGuard aGuard( m_aMutex );
1091
1092 if ( !m_pImpl )
1093 throw lang::DisposedException();
1094
1095 try
1096 {
1097 if ( !GetContent() )
1098 throw io::IOException(); // TODO: error handling
1099
1100 if ( !aName.getLength() )
1101 throw lang::IllegalArgumentException();
1102 }
1103 catch( uno::RuntimeException& )
1104 {
1105 throw;
1106 }
1107 catch ( uno::Exception& )
1108 {
1109 uno::Any aCaught( ::cppu::getCaughtException() );
1110 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1111 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1112 uno::UNO_QUERY ),
1113 aCaught );
1114 }
1115
1116 INetURLObject aURL( m_pImpl->m_aURL );
1117 aURL.Append( aName );
1118
1119 return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
1120 || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1121 }
1122
1123 //-----------------------------------------------
getElementType()1124 uno::Type SAL_CALL FSStorage::getElementType()
1125 {
1126 ::osl::MutexGuard aGuard( m_aMutex );
1127
1128 if ( !m_pImpl )
1129 throw lang::DisposedException();
1130
1131 // it is a multitype container
1132 return uno::Type();
1133 }
1134
1135 //-----------------------------------------------
hasElements()1136 sal_Bool SAL_CALL FSStorage::hasElements()
1137 {
1138 ::osl::MutexGuard aGuard( m_aMutex );
1139
1140 if ( !m_pImpl )
1141 throw lang::DisposedException();
1142
1143 if ( !GetContent() )
1144 throw io::IOException(); // TODO: error handling
1145
1146 uno::Sequence< ::rtl::OUString > aProps( 1 );
1147 aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
1148 ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1149
1150 try
1151 {
1152 uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1153 return ( xResultSet.is() && xResultSet->next() );
1154 }
1155 catch( uno::Exception& )
1156 {
1157 throw uno::RuntimeException();
1158 }
1159 }
1160
1161
1162 //____________________________________________________________________________________________________
1163 // XDisposable
1164 //____________________________________________________________________________________________________
1165
1166 //-----------------------------------------------
dispose()1167 void SAL_CALL FSStorage::dispose()
1168 {
1169 ::osl::MutexGuard aGuard( m_aMutex );
1170
1171 if ( !m_pImpl )
1172 throw lang::DisposedException();
1173
1174 if ( m_pImpl->m_pListenersContainer )
1175 {
1176 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1177 m_pImpl->m_pListenersContainer->disposeAndClear( aSource );
1178 }
1179
1180 delete m_pImpl;
1181 m_pImpl = NULL;
1182 }
1183
1184 //-----------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)1185 void SAL_CALL FSStorage::addEventListener(
1186 const uno::Reference< lang::XEventListener >& xListener )
1187 {
1188 ::osl::MutexGuard aGuard( m_aMutex );
1189
1190 if ( !m_pImpl )
1191 throw lang::DisposedException();
1192
1193 if ( !m_pImpl->m_pListenersContainer )
1194 m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
1195
1196 m_pImpl->m_pListenersContainer->addInterface( xListener );
1197 }
1198
1199 //-----------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)1200 void SAL_CALL FSStorage::removeEventListener(
1201 const uno::Reference< lang::XEventListener >& xListener )
1202 {
1203 ::osl::MutexGuard aGuard( m_aMutex );
1204
1205 if ( !m_pImpl )
1206 throw lang::DisposedException();
1207
1208 if ( m_pImpl->m_pListenersContainer )
1209 m_pImpl->m_pListenersContainer->removeInterface( xListener );
1210 }
1211
1212 //____________________________________________________________________________________________________
1213 // XPropertySet
1214 //____________________________________________________________________________________________________
1215
1216 //-----------------------------------------------
getPropertySetInfo()1217 uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
1218 {
1219 ::osl::MutexGuard aGuard( m_aMutex );
1220
1221 if ( !m_pImpl )
1222 throw lang::DisposedException();
1223
1224 //TODO:
1225 return uno::Reference< beans::XPropertySetInfo >();
1226 }
1227
1228
1229 //-----------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any &)1230 void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
1231 {
1232 ::osl::MutexGuard aGuard( m_aMutex );
1233
1234 if ( !m_pImpl )
1235 throw lang::DisposedException();
1236
1237 if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) )
1238 throw beans::PropertyVetoException(); // TODO
1239 else
1240 throw beans::UnknownPropertyException(); // TODO
1241 }
1242
1243
1244 //-----------------------------------------------
getPropertyValue(const::rtl::OUString & aPropertyName)1245 uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
1246 {
1247 ::osl::MutexGuard aGuard( m_aMutex );
1248
1249 if ( !m_pImpl )
1250 throw lang::DisposedException();
1251
1252 if ( aPropertyName.equalsAscii( "URL" ) )
1253 return uno::makeAny( m_pImpl->m_aURL );
1254 else if ( aPropertyName.equalsAscii( "OpenMode" ) )
1255 return uno::makeAny( m_pImpl->m_nMode );
1256
1257 throw beans::UnknownPropertyException(); // TODO
1258 }
1259
1260
1261 //-----------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1262 void SAL_CALL FSStorage::addPropertyChangeListener(
1263 const ::rtl::OUString& /*aPropertyName*/,
1264 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
1265 {
1266 ::osl::MutexGuard aGuard( m_aMutex );
1267
1268 if ( !m_pImpl )
1269 throw lang::DisposedException();
1270
1271 //TODO:
1272 }
1273
1274
1275 //-----------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1276 void SAL_CALL FSStorage::removePropertyChangeListener(
1277 const ::rtl::OUString& /*aPropertyName*/,
1278 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
1279 {
1280 ::osl::MutexGuard aGuard( m_aMutex );
1281
1282 if ( !m_pImpl )
1283 throw lang::DisposedException();
1284
1285 //TODO:
1286 }
1287
1288
1289 //-----------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1290 void SAL_CALL FSStorage::addVetoableChangeListener(
1291 const ::rtl::OUString& /*PropertyName*/,
1292 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1293 {
1294 ::osl::MutexGuard aGuard( m_aMutex );
1295
1296 if ( !m_pImpl )
1297 throw lang::DisposedException();
1298
1299 //TODO:
1300 }
1301
1302
1303 //-----------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1304 void SAL_CALL FSStorage::removeVetoableChangeListener(
1305 const ::rtl::OUString& /*PropertyName*/,
1306 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1307 {
1308 ::osl::MutexGuard aGuard( m_aMutex );
1309
1310 if ( !m_pImpl )
1311 throw lang::DisposedException();
1312
1313 //TODO:
1314 }
1315
1316 //____________________________________________________________________________________________________
1317 // XHierarchicalStorageAccess
1318 //____________________________________________________________________________________________________
1319 //-----------------------------------------------
openStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath,::sal_Int32 nOpenMode)1320 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode )
1321 {
1322 ::osl::MutexGuard aGuard( m_aMutex );
1323
1324 if ( !m_pImpl )
1325 throw lang::DisposedException();
1326
1327 if ( sStreamPath.toChar() == '/' )
1328 throw lang::IllegalArgumentException();
1329
1330 if ( !GetContent() )
1331 throw io::IOException(); // TODO: error handling
1332
1333 INetURLObject aBaseURL( m_pImpl->m_aURL );
1334 if ( !aBaseURL.setFinalSlash() )
1335 throw uno::RuntimeException();
1336
1337 INetURLObject aFileURL = INetURLObject::GetAbsURL(
1338 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1339 sStreamPath );
1340
1341 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1342 throw io::IOException();
1343
1344 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
1345 && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1346 throw io::IOException(); // TODO:
1347
1348 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
1349 uno::Reference< io::XStream > xResult;
1350 try
1351 {
1352 if ( nOpenMode & embed::ElementModes::WRITE )
1353 {
1354 if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1355 {
1356 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
1357 m_pImpl->m_xFactory->createInstance(
1358 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
1359 uno::UNO_QUERY_THROW );
1360 uno::Reference< io::XStream > xStream =
1361 xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
1362
1363 xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1364 }
1365 else
1366 {
1367 // TODO: test whether it really works for http and fwp
1368 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1369 STREAM_STD_WRITE );
1370 if ( pStream )
1371 {
1372 if ( !pStream->GetError() )
1373 {
1374 uno::Reference< io::XStream > xStream =
1375 uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
1376 xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1377 }
1378 else
1379 delete pStream;
1380 }
1381 }
1382
1383 if ( !xResult.is() )
1384 throw io::IOException();
1385
1386 if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
1387 {
1388 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
1389 xTrunc->truncate();
1390 }
1391 }
1392 else
1393 {
1394 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
1395 || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1396 throw io::IOException(); // TODO: access denied
1397
1398 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
1399 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
1400 xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
1401 }
1402 }
1403 catch( embed::InvalidStorageException& )
1404 {
1405 throw;
1406 }
1407 catch( lang::IllegalArgumentException& )
1408 {
1409 throw;
1410 }
1411 catch( packages::WrongPasswordException& )
1412 {
1413 throw;
1414 }
1415 catch( embed::StorageWrappedTargetException& )
1416 {
1417 throw;
1418 }
1419 catch( io::IOException& )
1420 {
1421 throw;
1422 }
1423 catch( uno::RuntimeException& )
1424 {
1425 throw;
1426 }
1427 catch( uno::Exception& )
1428 {
1429 uno::Any aCaught( ::cppu::getCaughtException() );
1430 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1431 uno::Reference< io::XInputStream >(),
1432 aCaught );
1433 }
1434
1435 return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW );
1436 }
1437
1438 //-----------------------------------------------
openEncryptedStreamElementByHierarchicalName(const::rtl::OUString &,::sal_Int32,const::rtl::OUString &)1439 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ )
1440 {
1441 throw packages::NoEncryptionException();
1442 }
1443
1444 //-----------------------------------------------
removeStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath)1445 void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath )
1446 {
1447 ::osl::MutexGuard aGuard( m_aMutex );
1448
1449 if ( !m_pImpl )
1450 throw lang::DisposedException();
1451
1452 if ( !GetContent() )
1453 throw io::IOException(); // TODO: error handling
1454
1455 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1456 INetURLObject aBaseURL( m_pImpl->m_aURL );
1457 if ( !aBaseURL.setFinalSlash() )
1458 throw uno::RuntimeException();
1459
1460 INetURLObject aFileURL = INetURLObject::GetAbsURL(
1461 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1462 sStreamPath );
1463
1464 if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1465 {
1466 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1467 throw lang::IllegalArgumentException();
1468 else
1469 throw container::NoSuchElementException(); // TODO:
1470 }
1471
1472 if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1473 throw io::IOException(); // TODO: error handling
1474 }
1475