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