xref: /trunk/main/sot/source/unoolestorage/xolesimplestorage.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sot.hxx"
30 #include <com/sun/star/lang/DisposedException.hpp>
31 #include <com/sun/star/io/XStream.hpp>
32 #include <com/sun/star/io/XInputStream.hpp>
33 #include <com/sun/star/io/XSeekable.hpp>
34 #include <com/sun/star/io/XTruncate.hpp>
35 
36 #include <comphelper/storagehelper.hxx>
37 
38 #include <unotools/ucbstreamhelper.hxx>
39 
40 #include <cppuhelper/exc_hlp.hxx>
41 
42 #include <sot/storinfo.hxx>
43 
44 #include "xolesimplestorage.hxx"
45 
46 
47 using namespace ::com::sun::star;
48 
49 const sal_Int32 nBytesCount = 32000;
50 
51 
52 // --------------------------------------------------------------------------------
53 OLESimpleStorage::OLESimpleStorage( uno::Reference< lang::XMultiServiceFactory > xFactory )
54 : m_bDisposed( sal_False )
55 , m_pStream( NULL )
56 , m_pStorage( NULL )
57 , m_pListenersContainer( NULL )
58 , m_xFactory( xFactory )
59 , m_bNoTemporaryCopy( sal_False )
60 {
61     OSL_ENSURE( m_xFactory.is(), "No factory is provided on creation!\n" );
62     if ( !m_xFactory.is() )
63         throw uno::RuntimeException();
64 }
65 
66 // --------------------------------------------------------------------------------
67 OLESimpleStorage::~OLESimpleStorage()
68 {
69     try {
70         m_refCount++;
71         dispose();
72     } catch( uno::Exception& )
73     {}
74 
75     if ( m_pListenersContainer )
76     {
77         delete m_pListenersContainer;
78         m_pListenersContainer = NULL;
79     }
80 }
81 
82 //-------------------------------------------------------------------------
83 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::impl_staticGetSupportedServiceNames()
84 {
85     uno::Sequence< ::rtl::OUString > aRet(1);
86     aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage");
87     return aRet;
88 }
89 
90 //-------------------------------------------------------------------------
91 ::rtl::OUString SAL_CALL OLESimpleStorage::impl_staticGetImplementationName()
92 {
93     return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.OLESimpleStorage");
94 }
95 
96 //-------------------------------------------------------------------------
97 uno::Reference< uno::XInterface > SAL_CALL OLESimpleStorage::impl_staticCreateSelfInstance(
98             const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
99 {
100     return uno::Reference< uno::XInterface >( *new OLESimpleStorage( xServiceManager ) );
101 }
102 
103 //-------------------------------------------------------------------------
104 void OLESimpleStorage::UpdateOriginal_Impl()
105 {
106     if ( !m_bNoTemporaryCopy )
107     {
108         uno::Reference< io::XSeekable > xSeek( m_xStream, uno::UNO_QUERY_THROW );
109         xSeek->seek( 0 );
110 
111         uno::Reference< io::XSeekable > xTempSeek( m_xTempStream, uno::UNO_QUERY_THROW );
112         sal_Int64 nPos = xTempSeek->getPosition();
113         xTempSeek->seek( 0 );
114 
115         uno::Reference< io::XInputStream > xTempInp = m_xTempStream->getInputStream();
116         uno::Reference< io::XOutputStream > xOutputStream = m_xStream->getOutputStream();
117         if ( !xTempInp.is() || !xOutputStream.is() )
118             throw uno::RuntimeException();
119 
120         uno::Reference< io::XTruncate > xTrunc( xOutputStream, uno::UNO_QUERY_THROW );
121         xTrunc->truncate();
122 
123         ::comphelper::OStorageHelper::CopyInputToOutput( xTempInp, xOutputStream );
124         xOutputStream->flush();
125         xTempSeek->seek( nPos );
126     }
127 }
128 
129 //-------------------------------------------------------------------------
130 void OLESimpleStorage::InsertInputStreamToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInputStream )
131     throw ( uno::Exception )
132 {
133     if ( !pStorage || !aName.getLength() || !xInputStream.is() )
134         throw uno::RuntimeException();
135 
136     if ( pStorage->IsContained( aName ) )
137         throw container::ElementExistException(); // TODO:
138 
139     BaseStorageStream* pNewStream = pStorage->OpenStream( aName );
140     if ( !pNewStream || pNewStream->GetError() || pStorage->GetError() )
141     {
142         if ( pNewStream )
143             DELETEZ( pNewStream );
144         pStorage->ResetError();
145         throw io::IOException(); // TODO
146     }
147 
148     try
149     {
150         uno::Sequence< sal_Int8 > aData( nBytesCount );
151         sal_Int32 nRead = 0;
152         do
153         {
154             nRead = xInputStream->readBytes( aData, nBytesCount );
155             if ( nRead < nBytesCount )
156                 aData.realloc( nRead );
157 
158             sal_Int32 nWritten = pNewStream->Write( aData.getArray(), nRead );
159             if ( nWritten < nRead )
160                 throw io::IOException();
161         } while( nRead == nBytesCount );
162     }
163     catch( uno::Exception& )
164     {
165         DELETEZ( pNewStream );
166         pStorage->Remove( aName );
167 
168         throw;
169     }
170 
171     DELETEZ( pNewStream );
172 }
173 
174 //-------------------------------------------------------------------------
175 void OLESimpleStorage::InsertNameAccessToStorage_Impl( BaseStorage* pStorage, ::rtl::OUString aName, const uno::Reference< container::XNameAccess >& xNameAccess )
176     throw ( uno::Exception )
177 {
178     if ( !pStorage || !aName.getLength() || !xNameAccess.is() )
179         throw uno::RuntimeException();
180 
181     if ( pStorage->IsContained( aName ) )
182         throw container::ElementExistException(); // TODO:
183 
184     BaseStorage* pNewStorage = pStorage->OpenStorage( aName );
185     if ( !pNewStorage || pNewStorage->GetError() || pStorage->GetError() )
186     {
187         if ( pNewStorage )
188             DELETEZ( pNewStorage );
189         pStorage->ResetError();
190         throw io::IOException(); // TODO
191     }
192 
193     try
194     {
195         uno::Sequence< ::rtl::OUString > aElements = xNameAccess->getElementNames();
196         for ( sal_Int32 nInd = 0; nInd < aElements.getLength(); nInd++ )
197         {
198             uno::Reference< io::XInputStream > xInputStream;
199             uno::Reference< container::XNameAccess > xSubNameAccess;
200             uno::Any aAny = xNameAccess->getByName( aElements[nInd] );
201             if ( aAny >>= xInputStream )
202                 InsertInputStreamToStorage_Impl( pNewStorage, aElements[nInd], xInputStream );
203             else if ( aAny >>= xSubNameAccess )
204                 InsertNameAccessToStorage_Impl( pNewStorage, aElements[nInd], xSubNameAccess );
205         }
206     }
207     catch( uno::Exception& )
208     {
209         DELETEZ( pNewStorage );
210         pStorage->Remove( aName );
211 
212         throw;
213     }
214 
215     DELETEZ( pNewStorage );
216 }
217 
218 //____________________________________________________________________________________________________
219 //  XInitialization
220 //____________________________________________________________________________________________________
221 
222 void SAL_CALL OLESimpleStorage::initialize( const uno::Sequence< uno::Any >& aArguments )
223         throw ( uno::Exception,
224                 uno::RuntimeException)
225 {
226     if ( m_pStream || m_pStorage )
227         throw io::IOException(); // TODO: already initilized
228 
229     sal_Int32 nArgNum = aArguments.getLength();
230     OSL_ENSURE( nArgNum >= 1 && nArgNum <= 2, "Wrong parameter number" );
231 
232     if ( nArgNum < 1 || nArgNum > 2 )
233         throw lang::IllegalArgumentException(); // TODO:
234 
235     uno::Reference< io::XStream > xStream;
236     uno::Reference< io::XInputStream > xInputStream;
237     if ( !( aArguments[0] >>= xStream ) && !( aArguments[0] >>= xInputStream ) )
238         throw lang::IllegalArgumentException(); // TODO:
239 
240     if ( nArgNum == 2 )
241     {
242         if ( !( aArguments[1] >>= m_bNoTemporaryCopy ) )
243             throw lang::IllegalArgumentException(); // TODO:
244     }
245 
246     if ( m_bNoTemporaryCopy )
247     {
248         // TODO: ???
249         // If the temporary stream is not created, the original stream must be wrapped
250         // since SvStream wrapper closes the stream is owns
251         if ( xInputStream.is() )
252         {
253             // the stream must be seekable for direct access
254             uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
255             m_pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream, sal_False );
256         }
257         else if ( xStream.is() )
258         {
259             // the stream must be seekable for direct access
260             uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
261             m_pStream = ::utl::UcbStreamHelper::CreateStream( xStream, sal_False );
262         }
263         else
264             throw lang::IllegalArgumentException(); // TODO:
265     }
266     else
267     {
268         uno::Reference < io::XStream > xTempFile(
269                 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
270                 uno::UNO_QUERY_THROW );
271         uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
272         uno::Reference< io::XOutputStream > xTempOut = xTempFile->getOutputStream();
273         if ( !xTempOut.is() )
274             throw uno::RuntimeException();
275 
276         if ( xInputStream.is() )
277         {
278             try
279             {
280                 uno::Reference< io::XSeekable > xSeek( xInputStream, uno::UNO_QUERY_THROW );
281                 xSeek->seek( 0 );
282             }
283             catch( uno::Exception& )
284             {}
285 
286             ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, xTempOut );
287             xTempOut->closeOutput();
288             xTempSeek->seek( 0 );
289             uno::Reference< io::XInputStream > xTempInput = xTempFile->getInputStream();
290             m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempInput, sal_False );
291         }
292         else if ( xStream.is() )
293         {
294             // not sure that the storage flashes the stream on commit
295             m_xStream = xStream;
296             m_xTempStream = xTempFile;
297 
298             uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
299             xSeek->seek( 0 );
300             uno::Reference< io::XInputStream > xInpStream = xStream->getInputStream();
301             if ( !xInpStream.is() || !xStream->getOutputStream().is() )
302                 throw uno::RuntimeException();
303 
304             ::comphelper::OStorageHelper::CopyInputToOutput( xInpStream, xTempOut );
305             xTempOut->flush();
306             xTempSeek->seek( 0 );
307 
308             m_pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False );
309         }
310         else
311             throw lang::IllegalArgumentException(); // TODO:
312     }
313 
314     if ( !m_pStream || m_pStream->GetError() )
315         throw io::IOException(); // TODO
316 
317     m_pStorage = new Storage( *m_pStream, sal_False );
318 }
319 
320 
321 //____________________________________________________________________________________________________
322 //  XNameContainer
323 //____________________________________________________________________________________________________
324 
325 // --------------------------------------------------------------------------------
326 void SAL_CALL OLESimpleStorage::insertByName( const ::rtl::OUString& aName, const uno::Any& aElement )
327         throw ( lang::IllegalArgumentException,
328                 container::ElementExistException,
329                 lang::WrappedTargetException,
330                 uno::RuntimeException)
331 {
332     ::osl::MutexGuard aGuard( m_aMutex );
333 
334     if ( m_bDisposed )
335         throw lang::DisposedException();
336 
337       if ( !m_pStorage )
338         throw uno::RuntimeException();
339 
340     uno::Reference< io::XStream > xStream;
341     uno::Reference< io::XInputStream > xInputStream;
342     uno::Reference< container::XNameAccess > xNameAccess;
343 
344     try
345     {
346         if ( !m_bNoTemporaryCopy && !m_xStream.is() )
347             throw io::IOException(); // TODO
348 
349         if ( aElement >>= xStream )
350             xInputStream = xStream->getInputStream();
351         else if ( !( aElement >>= xInputStream ) && !( aElement >>= xNameAccess ) )
352             throw lang::IllegalArgumentException(); // TODO:
353 
354         if ( xInputStream.is() )
355             InsertInputStreamToStorage_Impl( m_pStorage, aName, xInputStream );
356         else if ( xNameAccess.is() )
357             InsertNameAccessToStorage_Impl( m_pStorage, aName, xNameAccess );
358         else
359             throw uno::RuntimeException();
360     }
361     catch( uno::RuntimeException& )
362     {
363         throw;
364     }
365     catch( container::ElementExistException& )
366     {
367         throw;
368     }
369     catch( uno::Exception& e )
370     {
371         throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Insert has failed!" ) ),
372                                             uno::Reference< uno::XInterface >(),
373                                             uno::makeAny( e ) );
374     }
375 }
376 
377 // --------------------------------------------------------------------------------
378 void SAL_CALL OLESimpleStorage::removeByName( const ::rtl::OUString& aName )
379         throw ( container::NoSuchElementException,
380                 lang::WrappedTargetException,
381                 uno::RuntimeException)
382 {
383     ::osl::MutexGuard aGuard( m_aMutex );
384 
385     if ( m_bDisposed )
386         throw lang::DisposedException();
387 
388       if ( !m_pStorage )
389         throw uno::RuntimeException();
390 
391     if ( !m_bNoTemporaryCopy && !m_xStream.is() )
392         throw lang::WrappedTargetException(); // io::IOException(); // TODO
393 
394     if ( !m_pStorage->IsContained( aName ) )
395         throw container::NoSuchElementException(); // TODO:
396 
397     m_pStorage->Remove( aName );
398 
399     if ( m_pStorage->GetError() )
400     {
401         m_pStorage->ResetError();
402         throw lang::WrappedTargetException(); // io::IOException(); // TODO
403     }
404 }
405 
406 // --------------------------------------------------------------------------------
407 void SAL_CALL OLESimpleStorage::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement )
408         throw ( lang::IllegalArgumentException,
409                 container::NoSuchElementException,
410                 lang::WrappedTargetException,
411                 uno::RuntimeException)
412 {
413     ::osl::MutexGuard aGuard( m_aMutex );
414 
415     if ( m_bDisposed )
416         throw lang::DisposedException();
417 
418     removeByName( aName );
419 
420     try
421     {
422         insertByName( aName, aElement );
423     }
424     catch( container::ElementExistException& )
425     {
426         uno::Any aCaught( ::cppu::getCaughtException() );
427 
428         throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
429                                             uno::Reference< uno::XInterface >(),
430                                             aCaught );
431     }
432 }
433 
434 // --------------------------------------------------------------------------------
435 uno::Any SAL_CALL OLESimpleStorage::getByName( const ::rtl::OUString& aName )
436         throw ( container::NoSuchElementException,
437                 lang::WrappedTargetException,
438                 uno::RuntimeException )
439 {
440     ::osl::MutexGuard aGuard( m_aMutex );
441 
442     if ( m_bDisposed )
443         throw lang::DisposedException();
444 
445       if ( !m_pStorage )
446         throw uno::RuntimeException();
447 
448     if ( !m_pStorage->IsContained( aName ) )
449         throw container::NoSuchElementException(); // TODO:
450 
451     uno::Any aResult;
452 
453     uno::Reference< io::XStream > xTempFile(
454         m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
455         uno::UNO_QUERY );
456     uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
457     uno::Reference< io::XOutputStream > xOutputStream = xTempFile->getOutputStream();
458     uno::Reference< io::XInputStream > xInputStream = xTempFile->getInputStream();
459     if ( !xOutputStream.is() || !xInputStream.is() )
460         throw uno::RuntimeException();
461 
462     if ( m_pStorage->IsStorage( aName ) )
463     {
464         BaseStorage* pStrg = m_pStorage->OpenStorage( aName );
465         m_pStorage->ResetError();
466         if ( !pStrg )
467             throw io::IOException();
468 
469         SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xTempFile, sal_False ); // do not close the original stream
470         if ( !pStream )
471             throw uno::RuntimeException();
472 
473         BaseStorage* pNewStor = new Storage( *pStream, sal_False );
474         sal_Bool bSuccess =
475             ( pStrg->CopyTo( pNewStor ) && pNewStor->Commit() && !pNewStor->GetError() && !pStrg->GetError() );
476 
477         DELETEZ( pNewStor );
478         DELETEZ( pStrg );
479         DELETEZ( pStream );
480 
481         if ( !bSuccess )
482             throw uno::RuntimeException();
483 
484         uno::Sequence< uno::Any > aArgs( 2 );
485         aArgs[0] <<= xInputStream; // allow readonly access only
486         aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
487 
488         uno::Reference< container::XNameContainer > xResultNameContainer(
489             m_xFactory->createInstanceWithArguments(
490                     ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
491                     aArgs ),
492             uno::UNO_QUERY_THROW );
493 
494         aResult <<= xResultNameContainer;
495     }
496     else
497     {
498         BaseStorageStream* pStream = m_pStorage->OpenStream( aName, STREAM_READ | STREAM_SHARE_DENYALL | STREAM_NOCREATE );
499         if ( !pStream || pStream->GetError() || m_pStorage->GetError() )
500         {
501             m_pStorage->ResetError();
502             DELETEZ( pStream );
503             throw io::IOException(); // TODO
504         }
505 
506         try
507         {
508             uno::Sequence< sal_Int8 > aData( nBytesCount );
509             sal_Int32 nSize = nBytesCount;
510             sal_Int32 nRead = 0;
511             while( 0 != ( nRead = pStream->Read( aData.getArray(), nSize ) ) )
512             {
513                 if ( nRead < nSize )
514                 {
515                     nSize = nRead;
516                     aData.realloc( nSize );
517                 }
518 
519                 xOutputStream->writeBytes( aData );
520             }
521 
522             if ( pStream->GetError() )
523                 throw io::IOException(); // TODO
524 
525             xOutputStream->closeOutput();
526             xSeekable->seek( 0 );
527         }
528         catch( uno::RuntimeException& )
529         {
530             DELETEZ( pStream );
531             throw;
532         }
533         catch( uno::Exception& )
534         {
535             DELETEZ( pStream );
536             throw lang::WrappedTargetException(); // TODO:
537         }
538 
539         DELETEZ( pStream );
540 
541         aResult <<= xInputStream;
542     }
543 
544     return aResult;
545 }
546 
547 // --------------------------------------------------------------------------------
548 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getElementNames()
549         throw ( uno::RuntimeException )
550 {
551     ::osl::MutexGuard aGuard( m_aMutex );
552 
553     if ( m_bDisposed )
554         throw lang::DisposedException();
555 
556       if ( !m_pStorage )
557         throw uno::RuntimeException();
558 
559     SvStorageInfoList aList;
560     m_pStorage->FillInfoList( &aList );
561 
562     if ( m_pStorage->GetError() )
563     {
564         m_pStorage->ResetError();
565         throw uno::RuntimeException(); // TODO:
566     }
567 
568     uno::Sequence< ::rtl::OUString > aSeq( aList.Count() );
569     for ( sal_uInt32 nInd = 0; nInd < aList.Count(); nInd++ )
570         aSeq[nInd] = aList[nInd].GetName();
571 
572     return aSeq;
573 }
574 
575 // --------------------------------------------------------------------------------
576 sal_Bool SAL_CALL OLESimpleStorage::hasByName( const ::rtl::OUString& aName )
577         throw ( uno::RuntimeException )
578 {
579     ::osl::MutexGuard aGuard( m_aMutex );
580 
581     if ( m_bDisposed )
582         throw lang::DisposedException();
583 
584      if ( !m_pStorage )
585         throw uno::RuntimeException();
586 
587     sal_Bool bResult = m_pStorage->IsContained( aName );
588 
589     if ( m_pStorage->GetError() )
590     {
591         m_pStorage->ResetError();
592         throw uno::RuntimeException(); // TODO:
593     }
594 
595     return bResult;
596 }
597 
598 // --------------------------------------------------------------------------------
599 uno::Type SAL_CALL OLESimpleStorage::getElementType()
600         throw ( uno::RuntimeException )
601 {
602     ::osl::MutexGuard aGuard( m_aMutex );
603 
604     if ( m_bDisposed )
605         throw lang::DisposedException();
606 
607     return getCppuType( (const uno::Reference< io::XInputStream >*)NULL );
608 }
609 
610 // --------------------------------------------------------------------------------
611 sal_Bool SAL_CALL OLESimpleStorage::hasElements()
612         throw ( uno::RuntimeException )
613 {
614     ::osl::MutexGuard aGuard( m_aMutex );
615 
616     if ( m_bDisposed )
617         throw lang::DisposedException();
618 
619       if ( !m_pStorage )
620         throw uno::RuntimeException();
621 
622     SvStorageInfoList aList;
623     m_pStorage->FillInfoList( &aList );
624 
625     if ( m_pStorage->GetError() )
626     {
627         m_pStorage->ResetError();
628         throw uno::RuntimeException(); // TODO:
629     }
630 
631     return ( aList.Count() != 0 );
632 }
633 
634 //____________________________________________________________________________________________________
635 //  XComponent
636 //____________________________________________________________________________________________________
637 
638 // --------------------------------------------------------------------------------
639 void SAL_CALL OLESimpleStorage::dispose()
640         throw ( uno::RuntimeException )
641 {
642     ::osl::MutexGuard aGuard( m_aMutex );
643 
644     if ( m_bDisposed )
645         throw lang::DisposedException();
646 
647     if ( m_pListenersContainer )
648     {
649         lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
650         m_pListenersContainer->disposeAndClear( aSource );
651     }
652 
653     DELETEZ( m_pStorage );
654     DELETEZ( m_pStream );
655 
656     m_xStream = uno::Reference< io::XStream >();
657     m_xTempStream = uno::Reference< io::XStream >();
658 
659     m_bDisposed = sal_True;
660 }
661 
662 // --------------------------------------------------------------------------------
663 void SAL_CALL OLESimpleStorage::addEventListener(
664             const uno::Reference< lang::XEventListener >& xListener )
665         throw ( uno::RuntimeException )
666 {
667     ::osl::MutexGuard aGuard( m_aMutex );
668 
669     if ( m_bDisposed )
670         throw lang::DisposedException();
671 
672     if ( !m_pListenersContainer )
673         m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
674 
675     m_pListenersContainer->addInterface( xListener );
676 }
677 
678 // --------------------------------------------------------------------------------
679 void SAL_CALL OLESimpleStorage::removeEventListener(
680             const uno::Reference< lang::XEventListener >& xListener )
681         throw ( uno::RuntimeException )
682 {
683     ::osl::MutexGuard aGuard( m_aMutex );
684 
685     if ( m_bDisposed )
686         throw lang::DisposedException();
687 
688     if ( m_pListenersContainer )
689         m_pListenersContainer->removeInterface( xListener );
690 }
691 
692 //____________________________________________________________________________________________________
693 //  XTransactedObject
694 //____________________________________________________________________________________________________
695 
696 // --------------------------------------------------------------------------------
697 void SAL_CALL OLESimpleStorage::commit()
698         throw ( ::com::sun::star::io::IOException,
699                 ::com::sun::star::lang::WrappedTargetException,
700                 ::com::sun::star::uno::RuntimeException )
701 {
702     ::osl::MutexGuard aGuard( m_aMutex );
703 
704     if ( m_bDisposed )
705         throw lang::DisposedException();
706 
707      if ( !m_pStorage )
708         throw uno::RuntimeException();
709 
710     if ( !m_bNoTemporaryCopy && !m_xStream.is() )
711         throw io::IOException(); // TODO
712 
713     if ( !m_pStorage->Commit() || m_pStorage->GetError() )
714     {
715         m_pStorage->ResetError();
716         throw io::IOException(); // TODO
717     }
718 
719     UpdateOriginal_Impl();
720 }
721 
722 // --------------------------------------------------------------------------------
723 void SAL_CALL OLESimpleStorage::revert()
724         throw ( ::com::sun::star::io::IOException,
725                 ::com::sun::star::lang::WrappedTargetException,
726                 ::com::sun::star::uno::RuntimeException )
727 {
728     ::osl::MutexGuard aGuard( m_aMutex );
729 
730     if ( m_bDisposed )
731         throw lang::DisposedException();
732 
733      if ( !m_pStorage )
734         throw uno::RuntimeException();
735 
736     if ( !m_bNoTemporaryCopy && !m_xStream.is() )
737         throw io::IOException(); // TODO
738 
739     if ( !m_pStorage->Revert() || m_pStorage->GetError() )
740     {
741         m_pStorage->ResetError();
742         throw io::IOException(); // TODO
743     }
744 
745     UpdateOriginal_Impl();
746 }
747 
748 //____________________________________________________________________________________________________
749 //  XClassifiedObject
750 //____________________________________________________________________________________________________
751 
752 uno::Sequence< sal_Int8 > SAL_CALL OLESimpleStorage::getClassID()
753     throw ( uno::RuntimeException )
754 {
755     ::osl::MutexGuard aGuard( m_aMutex );
756 
757     if ( m_bDisposed )
758         throw lang::DisposedException();
759 
760     if ( !m_pStorage )
761         throw uno::RuntimeException();
762 
763     return m_pStorage->GetClassName().GetByteSequence();
764 }
765 
766 ::rtl::OUString SAL_CALL OLESimpleStorage::getClassName()
767     throw ( uno::RuntimeException )
768 {
769     return ::rtl::OUString();
770 }
771 
772 void SAL_CALL OLESimpleStorage::setClassInfo( const uno::Sequence< sal_Int8 >& /*aClassID*/,
773                             const ::rtl::OUString& /*sClassName*/ )
774         throw ( lang::NoSupportException,
775                 uno::RuntimeException )
776 {
777     throw lang::NoSupportException();
778 }
779 
780 //____________________________________________________________________________________________________
781 //  XServiceInfo
782 //____________________________________________________________________________________________________
783 
784 // --------------------------------------------------------------------------------
785 ::rtl::OUString SAL_CALL OLESimpleStorage::getImplementationName()
786         throw ( uno::RuntimeException )
787 {
788     return impl_staticGetImplementationName();
789 }
790 
791 // --------------------------------------------------------------------------------
792 ::sal_Bool SAL_CALL OLESimpleStorage::supportsService( const ::rtl::OUString& ServiceName )
793         throw ( uno::RuntimeException )
794 {
795     uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
796 
797     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
798         if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
799             return sal_True;
800 
801     return sal_False;
802 }
803 
804 // --------------------------------------------------------------------------------
805 uno::Sequence< ::rtl::OUString > SAL_CALL OLESimpleStorage::getSupportedServiceNames()
806         throw ( uno::RuntimeException )
807 {
808     return impl_staticGetSupportedServiceNames();
809 }
810 
811 
812