update dev300-m58
[ooovba.git] / dbaccess / source / core / dataaccess / ModelImpl.cxx
blob1148cf44071b6d662484277749669eed23f376bc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ModelImpl.cxx,v $
10 * $Revision: 1.25.6.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #include "commandcontainer.hxx"
35 #include "connection.hxx"
36 #include "core_resource.hrc"
37 #include "core_resource.hxx"
38 #include "databasecontext.hxx"
39 #include "databasedocument.hxx"
40 #include "datasource.hxx"
41 #include "dbastrings.hrc"
42 #include "ModelImpl.hxx"
43 #include "userinformation.hxx"
45 /** === begin UNO includes === **/
46 #include <com/sun/star/container/XSet.hpp>
47 #include <com/sun/star/document/MacroExecMode.hpp>
48 #include <com/sun/star/embed/XTransactedObject.hpp>
49 #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
50 #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
51 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
52 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
53 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
54 #include <com/sun/star/form/XLoadable.hpp>
55 /** === end UNO includes === **/
57 #include <comphelper/interaction.hxx>
58 #include <comphelper/mediadescriptor.hxx>
59 #include <comphelper/namedvaluecollection.hxx>
60 #include <comphelper/seqstream.hxx>
61 #include <comphelper/sequence.hxx>
62 #include <connectivity/dbexception.hxx>
63 #include <cppuhelper/exc_hlp.hxx>
64 #include <cppuhelper/typeprovider.hxx>
65 #include <rtl/digest.h>
66 #include <sfx2/signaturestate.hxx>
67 #include <tools/debug.hxx>
68 #include <tools/diagnose_ex.h>
69 #include <tools/errcode.hxx>
70 #include <tools/urlobj.hxx>
71 #include <unotools/sharedunocomponent.hxx>
73 #include <algorithm>
75 using namespace ::com::sun::star::document;
76 using namespace ::com::sun::star::sdbc;
77 using namespace ::com::sun::star::sdbcx;
78 using namespace ::com::sun::star::sdb;
79 using namespace ::com::sun::star::beans;
80 using namespace ::com::sun::star::uno;
81 using namespace ::com::sun::star::lang;
82 using namespace ::com::sun::star::embed;
83 using namespace ::com::sun::star::container;
84 using namespace ::com::sun::star::util;
85 using namespace ::com::sun::star::io;
86 using namespace ::com::sun::star::task;
87 using namespace ::com::sun::star::ucb;
88 using namespace ::com::sun::star::frame;
89 using namespace ::com::sun::star::view;
90 using namespace ::com::sun::star::task;
91 using namespace ::com::sun::star::reflection;
92 using namespace ::com::sun::star::script;
93 using namespace ::cppu;
94 using namespace ::osl;
95 using namespace ::vos;
96 using namespace ::dbtools;
97 using namespace ::comphelper;
98 namespace css = ::com::sun::star;
100 //........................................................................
101 namespace dbaccess
103 //........................................................................
105 //============================================================
106 //= VosMutexFacade
107 //============================================================
108 //------------------------------------------------------------------------
109 VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex )
110 :m_rMutex( _rMutex )
114 //------------------------------------------------------------------------
115 void SAL_CALL VosMutexFacade::acquire()
117 m_rMutex.acquire();
120 //------------------------------------------------------------------------
121 sal_Bool SAL_CALL VosMutexFacade::tryToAcquire()
123 return m_rMutex.tryToAcquire();
126 //------------------------------------------------------------------------
127 void SAL_CALL VosMutexFacade::release()
129 m_rMutex.release();
132 //============================================================
133 //= DocumentStorageAccess
134 //============================================================
135 DBG_NAME( DocumentStorageAccess )
136 class DocumentStorageAccess : public ::cppu::WeakImplHelper2< XDocumentSubStorageSupplier
137 , XTransactionListener >
139 typedef ::std::map< ::rtl::OUString, Reference< XStorage > > NamedStorages;
141 ::osl::Mutex m_aMutex;
142 /// all sub storages which we ever gave to the outer world
143 NamedStorages m_aExposedStorages;
144 ODatabaseModelImpl* m_pModelImplementation;
145 bool m_bPropagateCommitToRoot;
147 public:
148 DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation )
149 :m_pModelImplementation( &_rModelImplementation )
150 ,m_bPropagateCommitToRoot( true )
152 DBG_CTOR( DocumentStorageAccess, NULL );
155 protected:
156 ~DocumentStorageAccess()
158 DBG_DTOR( DocumentStorageAccess, NULL );
161 public:
162 void dispose();
164 void suspendCommitPropagation()
166 DBG_ASSERT( m_bPropagateCommitToRoot, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" );
167 m_bPropagateCommitToRoot = false;
169 void resumeCommitPropagation()
171 DBG_ASSERT( !m_bPropagateCommitToRoot, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" );
172 m_bPropagateCommitToRoot = true;
175 // XDocumentSubStorageSupplier
176 virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 nMode ) throw (RuntimeException);
177 virtual Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (IOException, RuntimeException);
179 // XTransactionListener
180 virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
181 virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
182 virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
183 virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
185 // XEventListener
186 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
189 //--------------------------------------------------------------------------
190 void DocumentStorageAccess::dispose()
192 ::osl::MutexGuard aGuard( m_aMutex );
194 for ( NamedStorages::iterator loop = m_aExposedStorages.begin();
195 loop != m_aExposedStorages.end();
196 ++loop
201 Reference< XTransactionBroadcaster > xBroadcaster( loop->second, UNO_QUERY );
202 if ( xBroadcaster.is() )
203 xBroadcaster->removeTransactionListener( this );
205 catch( const Exception& )
207 DBG_UNHANDLED_EXCEPTION();
211 m_aExposedStorages.clear();
213 m_pModelImplementation = NULL;
216 //--------------------------------------------------------------------------
217 Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 nMode ) throw (RuntimeException)
219 ::osl::MutexGuard aGuard( m_aMutex );
220 NamedStorages::iterator pos = m_aExposedStorages.find( aStorageName );
221 if ( pos == m_aExposedStorages.end() )
223 Reference< XStorage > xResult = m_pModelImplementation->getStorage( aStorageName, nMode );
224 Reference< XTransactionBroadcaster > xBroadcaster( xResult, UNO_QUERY );
225 if ( xBroadcaster.is() )
226 xBroadcaster->addTransactionListener( this );
228 pos = m_aExposedStorages.insert( NamedStorages::value_type( aStorageName, xResult ) ).first;
231 return pos->second;
234 //--------------------------------------------------------------------------
235 Sequence< ::rtl::OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (IOException, RuntimeException)
237 Reference< XStorage > xRootStor( m_pModelImplementation->getRootStorage() );
238 if ( !xRootStor.is() )
239 return Sequence< ::rtl::OUString >();
241 ::std::vector< ::rtl::OUString > aNames;
243 Reference< XNameAccess > xNames( xRootStor, UNO_QUERY_THROW );
244 Sequence< ::rtl::OUString > aElementNames( xNames->getElementNames() );
245 for ( sal_Int32 i=0; i<aElementNames.getLength(); ++i )
247 if ( xRootStor->isStorageElement( aElementNames[i] ) )
248 aNames.push_back( aElementNames[i] );
250 return aNames.empty()
251 ? Sequence< ::rtl::OUString >()
252 : Sequence< ::rtl::OUString >( &aNames[0], aNames.size() );
255 //--------------------------------------------------------------------------
256 void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
258 // not interested in
261 //--------------------------------------------------------------------------
262 void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent ) throw (RuntimeException)
264 ::osl::MutexGuard aGuard( m_aMutex );
266 if ( m_pModelImplementation )
267 m_pModelImplementation->setModified( sal_True );
269 if ( m_pModelImplementation && m_bPropagateCommitToRoot )
271 Reference< XStorage > xStorage( aEvent.Source, UNO_QUERY );
272 if ( m_pModelImplementation->isDatabaseStorage( xStorage ) )
274 m_pModelImplementation->commitRootStorage();
279 //--------------------------------------------------------------------------
280 void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
282 // not interested in
285 //--------------------------------------------------------------------------
286 void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& /*aEvent*/ ) throw (RuntimeException)
288 // not interested in
291 //--------------------------------------------------------------------------
292 void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source ) throw ( RuntimeException )
294 ODatabaseModelImpl* pImpl = m_pModelImplementation;
295 if ( pImpl )
296 pImpl->disposing( Source );
298 for ( NamedStorages::iterator find = m_aExposedStorages.begin();
299 find != m_aExposedStorages.end();
300 ++find
302 if ( find->second == Source.Source )
304 m_aExposedStorages.erase( find );
305 break;
309 //============================================================
310 //= ODatabaseModelImpl
311 //============================================================
312 DBG_NAME(ODatabaseModelImpl)
313 //--------------------------------------------------------------------------
314 ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >& _rxFactory, ODatabaseContext& _rDBContext )
315 :m_xModel()
316 ,m_xDataSource()
317 ,m_pStorageAccess( NULL )
318 ,m_aMutex()
319 ,m_aMutexFacade( m_aMutex )
320 ,m_aContainer(4)
321 ,m_aStorages()
322 ,m_aMacroMode( *this )
323 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
324 ,m_pDBContext( &_rDBContext )
325 ,m_refCount(0)
326 ,m_aEmbeddedMacros()
327 ,m_bModificationLock( false )
328 ,m_bDocumentInitialized( false )
329 ,m_aContext( _rxFactory )
330 ,m_nLoginTimeout(0)
331 ,m_bReadOnly(sal_False)
332 ,m_bPasswordRequired(sal_False)
333 ,m_bSuppressVersionColumns(sal_True)
334 ,m_bModified(sal_False)
335 ,m_bDocumentReadOnly(sal_False)
336 ,m_bDisposingSubStorages( sal_False )
337 ,m_pSharedConnectionManager(NULL)
338 ,m_nControllerLockCount(0)
340 // some kind of default
341 DBG_CTOR(ODatabaseModelImpl,NULL);
342 m_sConnectURL = ::rtl::OUString::createFromAscii("jdbc:");
343 m_aTableFilter.realloc(1);
344 m_aTableFilter[0] = ::rtl::OUString::createFromAscii("%");
345 impl_construct_nothrow();
348 //--------------------------------------------------------------------------
349 ODatabaseModelImpl::ODatabaseModelImpl(
350 const ::rtl::OUString& _rRegistrationName,
351 const Reference< XMultiServiceFactory >& _rxFactory,
352 ODatabaseContext& _rDBContext
354 :m_xModel()
355 ,m_xDataSource()
356 ,m_pStorageAccess( NULL )
357 ,m_aMutex()
358 ,m_aMutexFacade( m_aMutex )
359 ,m_aContainer(4)
360 ,m_aStorages()
361 ,m_aMacroMode( *this )
362 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
363 ,m_pDBContext( &_rDBContext )
364 ,m_refCount(0)
365 ,m_aEmbeddedMacros()
366 ,m_bModificationLock( false )
367 ,m_bDocumentInitialized( false )
368 ,m_aContext( _rxFactory )
369 ,m_sName(_rRegistrationName)
370 ,m_nLoginTimeout(0)
371 ,m_bReadOnly(sal_False)
372 ,m_bPasswordRequired(sal_False)
373 ,m_bSuppressVersionColumns(sal_True)
374 ,m_bModified(sal_False)
375 ,m_bDocumentReadOnly(sal_False)
376 ,m_bDisposingSubStorages( sal_False )
377 ,m_pSharedConnectionManager(NULL)
378 ,m_nControllerLockCount(0)
380 DBG_CTOR(ODatabaseModelImpl,NULL);
381 impl_construct_nothrow();
384 //--------------------------------------------------------------------------
385 ODatabaseModelImpl::~ODatabaseModelImpl()
387 DBG_DTOR(ODatabaseModelImpl,NULL);
390 // -----------------------------------------------------------------------------
391 void ODatabaseModelImpl::impl_construct_nothrow()
393 // create the property bag to hold the settings (also known as "Info" property)
396 // the set of property value types in the bag is limited:
397 Sequence< Type > aAllowedTypes(6);
398 Type* pAllowedType = aAllowedTypes.getArray();
399 *pAllowedType++ = ::getCppuType( static_cast< sal_Bool* >( NULL ) );
400 *pAllowedType++ = ::getCppuType( static_cast< double* >( NULL ) );
401 *pAllowedType++ = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
402 *pAllowedType++ = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
403 *pAllowedType++ = ::getCppuType( static_cast< sal_Int16* >( NULL ) );
404 *pAllowedType++ = ::getCppuType( static_cast< Sequence< Any >* >( NULL ) );
406 Sequence< Any > aInitArgs( 2 );
407 aInitArgs[0] <<= NamedValue(
408 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutomaticAddition" ) ),
409 makeAny( (sal_Bool)sal_True )
411 aInitArgs[1] <<= NamedValue(
412 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowedTypes" ) ),
413 makeAny( aAllowedTypes )
416 m_xSettings.set( m_aContext.createComponentWithArguments( "com.sun.star.beans.PropertyBag", aInitArgs ), UNO_QUERY_THROW );
418 // insert the default settings
419 Reference< XPropertyContainer > xContainer( m_xSettings, UNO_QUERY_THROW );
420 Reference< XSet > xSettingsSet( m_xSettings, UNO_QUERY_THROW );
421 const AsciiPropertyValue* pSettings = getDefaultDataSourceSettings();
422 for ( ; pSettings->AsciiName; ++pSettings )
424 if ( !pSettings->DefaultValue.hasValue() )
426 Property aProperty(
427 ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
429 ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ),
430 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID
432 xSettingsSet->insert( makeAny( aProperty ) );
434 else
436 xContainer->addProperty(
437 ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
438 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT,
439 pSettings->DefaultValue
444 catch( const Exception& )
446 DBG_UNHANDLED_EXCEPTION();
448 m_pDBContext->appendAtTerminateListener(*this);
451 // -----------------------------------------------------------------------------
452 namespace
454 // .........................................................................
455 ::rtl::OUString lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType )
457 const sal_Char* pAsciiName( NULL );
458 switch ( _eType )
460 case ODatabaseModelImpl::E_FORM: pAsciiName = "forms"; break;
461 case ODatabaseModelImpl::E_REPORT: pAsciiName = "reports"; break;
462 case ODatabaseModelImpl::E_QUERY: pAsciiName = "queries"; break;
463 case ODatabaseModelImpl::E_TABLE: pAsciiName = "tables"; break;
464 default:
465 throw RuntimeException();
467 return ::rtl::OUString::createFromAscii( pAsciiName );
470 // .........................................................................
471 bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl& _rObjectDefinitions, const Reference< XStorage >& _rxContainerStorage )
473 bool bSomeDocHasMacros = false;
475 for ( ODefinitionContainer_Impl::const_iterator object = _rObjectDefinitions.begin();
476 ( object != _rObjectDefinitions.end() ) && !bSomeDocHasMacros;
477 ++object
480 #if OSL_DEBUG_LEVEL > 0
481 const ::rtl::OUString& rName( object->first ); (void)rName;
482 #endif
484 const TContentPtr& rDefinition( object->second );
485 const ::rtl::OUString& rPersistentName( rDefinition->m_aProps.sPersistentName );
487 if ( !rPersistentName.getLength() )
488 { // it's a logical sub folder used to organize the real objects
489 const ODefinitionContainer_Impl& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl& >( *rDefinition.get() ) );
490 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions, _rxContainerStorage );
491 continue;
494 bSomeDocHasMacros = ODatabaseModelImpl::objectHasMacros( _rxContainerStorage, rPersistentName );
496 return bSomeDocHasMacros;
499 // .........................................................................
500 bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl& _rModel, const ODatabaseModelImpl::ObjectType _eType )
502 bool bSomeDocHasMacros = false;
504 const OContentHelper_Impl& rContainerData( *_rModel.getObjectContainer( _eType ).get() );
505 const ODefinitionContainer_Impl& rObjectDefinitions = dynamic_cast< const ODefinitionContainer_Impl& >( rContainerData );
509 Reference< XStorage > xContainerStorage( _rModel.getStorage(
510 _rModel.getObjectContainerStorageName( _eType ), ElementModes::READWRITE ) );
511 // note the READWRITE here: If the storage already existed before, then the OpenMode will
512 // be ignored, anyway.
513 // If the storage did not yet exist, then it will be created. If the database document
514 // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise,
515 // the storage will in fact be created as READWRITE. While this is not strictly necessary
516 // for this particular use case here, it is required since the storage is *cached*, and
517 // later use cases will need the READWRITE mode.
519 if ( xContainerStorage.is() )
520 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rObjectDefinitions, xContainerStorage );
522 catch( const Exception& )
524 DBG_UNHANDLED_EXCEPTION();
525 // be on the safe side: If we can't reliably determine whether there are macros,
526 // assume there actually are. Better this way, than the other way round.
527 bSomeDocHasMacros = true;
530 return bSomeDocHasMacros;
534 // -----------------------------------------------------------------------------
535 bool ODatabaseModelImpl::objectHasMacros( const Reference< XStorage >& _rxContainerStorage, const ::rtl::OUString& _rPersistentName )
537 OSL_PRECOND( _rxContainerStorage.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" );
539 bool bHasMacros = true;
542 if ( !_rxContainerStorage->hasByName( _rPersistentName ) )
543 return false;
545 Reference< XStorage > xObjectStor( _rxContainerStorage->openStorageElement(
546 _rPersistentName, ElementModes::READ ) );
548 bHasMacros = ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor );
550 catch( const Exception& )
552 DBG_UNHANDLED_EXCEPTION();
554 return bHasMacros;
557 // -----------------------------------------------------------------------------
558 void ODatabaseModelImpl::reset()
560 m_bReadOnly = sal_False;
561 ::std::vector< TContentPtr > aEmptyContainers( 4 );
562 m_aContainer.swap( aEmptyContainers );
564 if ( m_pStorageAccess )
566 m_pStorageAccess->dispose();
567 m_pStorageAccess->release();
568 m_pStorageAccess = NULL;
571 // -----------------------------------------------------------------------------
572 void SAL_CALL ODatabaseModelImpl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
574 Reference<XConnection> xCon(Source.Source,UNO_QUERY);
575 if ( xCon.is() )
577 bool bStore = false;
578 OWeakConnectionArray::iterator aEnd = m_aConnections.end();
579 for (OWeakConnectionArray::iterator i = m_aConnections.begin(); aEnd != i; ++i)
581 if ( xCon == i->get() )
583 *i = OWeakConnection();
584 bStore = true;
585 break;
589 if ( bStore )
590 commitRootStorage();
592 else // storage
594 if ( !m_bDisposingSubStorages )
596 Reference<XStorage> xStorage(Source.Source,UNO_QUERY);
597 TStorages::iterator aFind = ::std::find_if(m_aStorages.begin(),m_aStorages.end(),
598 ::std::compose1(::std::bind2nd(::std::equal_to<Reference<XStorage> >(),xStorage),::std::select2nd<TStorages::value_type>()));
599 if ( aFind != m_aStorages.end() )
600 m_aStorages.erase(aFind);
604 //------------------------------------------------------------------------------
605 void ODatabaseModelImpl::clearConnections()
607 OWeakConnectionArray aConnections;
608 aConnections.swap( m_aConnections );
610 Reference< XConnection > xConn;
611 OWeakConnectionArray::iterator aEnd = aConnections.end();
612 for ( OWeakConnectionArray::iterator i = aConnections.begin(); aEnd != i; ++i )
614 xConn = *i;
615 if ( xConn.is() )
619 xConn->close();
621 catch(const Exception&)
623 DBG_UNHANDLED_EXCEPTION();
628 m_pSharedConnectionManager = NULL;
629 m_xSharedConnectionManager = NULL;
631 //------------------------------------------------------------------------------
632 void ODatabaseModelImpl::dispose()
634 // dispose the data source and the model
637 Reference< XDataSource > xDS( m_xDataSource );
638 ::comphelper::disposeComponent( xDS );
640 Reference< XModel > xModel( m_xModel );
641 ::comphelper::disposeComponent( xModel );
643 catch( const Exception& )
645 DBG_UNHANDLED_EXCEPTION();
647 m_xDataSource = WeakReference<XDataSource>();
648 m_xModel = WeakReference< XModel >();
650 ::std::vector<TContentPtr>::iterator aIter = m_aContainer.begin();
651 ::std::vector<TContentPtr>::iterator aEnd = m_aContainer.end();
652 for (;aIter != aEnd ; ++aIter)
654 if ( aIter->get() )
655 (*aIter)->m_pDataSource = NULL;
657 m_aContainer.clear();
659 clearConnections();
661 m_xNumberFormatsSupplier = NULL;
665 sal_Bool bStore = commitEmbeddedStorage();
666 disposeStorages();
667 if ( bStore )
668 commitRootStorage();
670 impl_switchToStorage_throw( NULL );
672 catch( const Exception& )
674 DBG_UNHANDLED_EXCEPTION();
677 if ( m_pStorageAccess )
679 m_pStorageAccess->dispose();
680 m_pStorageAccess->release();
681 m_pStorageAccess = NULL;
684 // -----------------------------------------------------------------------------
685 const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormatsSupplier()
687 if (!m_xNumberFormatsSupplier.is())
689 // the arguments : the locale of the current user
690 UserInformation aUserInfo;
691 Sequence< Any > aArguments(1);
692 aArguments.getArray()[0] <<= aUserInfo.getUserLanguage();
694 m_xNumberFormatsSupplier.set(
695 m_aContext.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aArguments ), UNO_QUERY_THROW );
696 DBG_ASSERT(m_xNumberFormatsSupplier.is(), "ODatabaseModelImpl::getNumberFormatsSupplier : could not instantiate the formats supplier !");
698 return m_xNumberFormatsSupplier;
700 // -----------------------------------------------------------------------------
701 void ODatabaseModelImpl::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArgs )
703 ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs );
705 ::rtl::OUString sDocumentLocation( aMediaDescriptor.getOrDefault( "SalvagedFile", _rURL ) );
706 if ( !sDocumentLocation.getLength() )
707 // this indicates "the document is being recovered, but _rURL already is the real document URL,
708 // not the temporary document location"
709 sDocumentLocation = _rURL;
711 if ( aMediaDescriptor.has( "SalvagedFile" ) )
712 aMediaDescriptor.remove( "SalvagedFile" );
714 m_aArgs = stripLoadArguments( aMediaDescriptor );
716 switchToURL( sDocumentLocation, _rURL );
719 // -----------------------------------------------------------------------------
720 Sequence< PropertyValue > ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments )
722 OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" );
723 OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" );
725 ::comphelper::NamedValueCollection aMutableArgs( _rArguments );
726 aMutableArgs.remove( "Model" );
727 aMutableArgs.remove( "ViewName" );
728 return aMutableArgs.getPropertyValues();
731 // -----------------------------------------------------------------------------
732 void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
734 m_bDisposingSubStorages = sal_True;
736 TStorages::iterator aEnd = m_aStorages.end();
737 for ( TStorages::iterator aIter = m_aStorages.begin();
738 aIter != aEnd ;
739 ++aIter
744 ::comphelper::disposeComponent( aIter->second );
746 catch( const Exception& )
748 DBG_UNHANDLED_EXCEPTION();
751 m_aStorages.clear();
753 m_bDisposingSubStorages = sal_False;
755 // -----------------------------------------------------------------------------
756 Reference< XSingleServiceFactory > ODatabaseModelImpl::createStorageFactory() const
758 return Reference< XSingleServiceFactory >( m_aContext.createComponent( "com.sun.star.embed.StorageFactory" ), UNO_QUERY_THROW );
760 // -----------------------------------------------------------------------------
761 void ODatabaseModelImpl::commitRootStorage()
763 Reference< XStorage > xStorage( getOrCreateRootStorage() );
764 #if OSL_DEBUG_LEVEL > 0
765 bool bSuccess =
766 #endif
767 commitStorageIfWriteable_ignoreErrors( xStorage );
768 OSL_ENSURE( bSuccess || !xStorage.is(),
769 "ODatabaseModelImpl::commitRootStorage: could commit the storage!" );
771 // -----------------------------------------------------------------------------
772 Reference< XStorage > ODatabaseModelImpl::getOrCreateRootStorage()
774 if ( !m_xDocumentStorage.is() )
776 Reference< XSingleServiceFactory> xStorageFactory = createStorageFactory();
777 if ( xStorageFactory.is() )
779 Any aSource;
780 ::comphelper::NamedValueCollection aArgs( m_aArgs );
782 aSource = aArgs.get( "Stream" );
783 if ( !aSource.hasValue() )
784 aSource = aArgs.get( "InputStream" );
785 if ( !aSource.hasValue() && m_sDocFileLocation.getLength() )
786 aSource <<= m_sDocFileLocation;
787 // TODO: shouldn't we also check URL?
789 OSL_ENSURE( aSource.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" );
791 if ( aSource.hasValue() )
793 Sequence< Any > aStorageCreationArgs(2);
794 aStorageCreationArgs[0] = aSource;
795 aStorageCreationArgs[1] <<= ElementModes::READWRITE;
797 Reference< XStorage > xDocumentStorage;
800 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
802 catch( const Exception& )
804 m_bDocumentReadOnly = sal_True;
805 aStorageCreationArgs[1] <<= ElementModes::READ;
808 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
810 catch( const Exception& )
812 DBG_UNHANDLED_EXCEPTION();
816 impl_switchToStorage_throw( xDocumentStorage );
820 return m_xDocumentStorage.getTyped();
822 // -----------------------------------------------------------------------------
823 DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess()
825 if ( !m_pStorageAccess )
827 m_pStorageAccess = new DocumentStorageAccess( *this );
828 m_pStorageAccess->acquire();
830 return m_pStorageAccess;
833 // -----------------------------------------------------------------------------
834 void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess )
836 m_xModel = Reference< XModel >();
838 // Basic libraries and Dialog libraries are a model facet, though held at this impl class.
839 // They automatically dispose themself when the model they belong to is being disposed.
840 // So, to not be tempted to do anything with them, again, we reset them.
841 m_xBasicLibraries.clear();
842 m_xDialogLibraries.clear();
844 m_bDocumentInitialized = _wasInitialized;
847 // -----------------------------------------------------------------------------
848 Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier()
850 return getDocumentStorageAccess();
852 // -----------------------------------------------------------------------------
853 Reference<XStorage> ODatabaseModelImpl::getStorage( const ::rtl::OUString& _sStorageName, sal_Int32 _nMode )
855 OSL_ENSURE(_sStorageName.getLength(),"ODatabaseModelImpl::getStorage: Invalid storage name!");
856 Reference<XStorage> xStorage;
857 TStorages::iterator aFind = m_aStorages.find(_sStorageName);
858 if ( aFind == m_aStorages.end() )
862 Reference< XStorage > xMyStorage( getOrCreateRootStorage() );
863 if ( xMyStorage.is() )
865 sal_Int32 nMode = m_bDocumentReadOnly ? ElementModes::READ : _nMode;
866 if ( nMode == ElementModes::READ )
868 Reference< XNameAccess > xSubStorageNames( xMyStorage, UNO_QUERY );
869 if ( xSubStorageNames.is() && !xSubStorageNames->hasByName( _sStorageName ) )
870 return xStorage;
873 xStorage = xMyStorage->openStorageElement( _sStorageName, nMode );
874 Reference< XTransactionBroadcaster > xBroad( xStorage, UNO_QUERY );
875 if ( xBroad.is() )
876 xBroad->addTransactionListener( getDocumentStorageAccess() );
877 aFind = m_aStorages.insert( TStorages::value_type( _sStorageName, xStorage ) ).first;
880 catch( const Exception& )
882 DBG_UNHANDLED_EXCEPTION();
886 if ( aFind != m_aStorages.end() )
887 xStorage = aFind->second;
889 return xStorage;
891 // -----------------------------------------------------------------------------
892 sal_Bool ODatabaseModelImpl::commitEmbeddedStorage( sal_Bool _bPreventRootCommits )
894 if ( _bPreventRootCommits && m_pStorageAccess )
895 m_pStorageAccess->suspendCommitPropagation();
897 sal_Bool bStore = sal_False;
900 TStorages::iterator aFind = m_aStorages.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database")));
901 if ( aFind != m_aStorages.end() )
902 bStore = commitStorageIfWriteable(aFind->second);
904 catch(Exception&)
906 OSL_ENSURE(0,"Exception Caught: Could not store embedded database!");
909 if ( _bPreventRootCommits && m_pStorageAccess )
910 m_pStorageAccess->resumeCommitPropagation();
912 return bStore;
916 // -----------------------------------------------------------------------------
917 namespace
919 bool lcl_storageIsWritable_nothrow( const Reference< XStorage >& _rxStorage )
921 if ( !_rxStorage.is() )
922 return false;
924 sal_Int32 nMode = ElementModes::READ;
927 Reference< XPropertySet > xStorageProps( _rxStorage, UNO_QUERY_THROW );
928 xStorageProps->getPropertyValue(
929 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) ) >>= nMode;
931 catch( const Exception& )
933 DBG_UNHANDLED_EXCEPTION();
935 return ( nMode & ElementModes::WRITE ) != 0;
939 // -----------------------------------------------------------------------------
940 bool ODatabaseModelImpl::commitStorageIfWriteable( const Reference< XStorage >& _rxStorage ) SAL_THROW(( IOException, WrappedTargetException, RuntimeException ))
942 bool bSuccess = false;
943 Reference<XTransactedObject> xTrans( _rxStorage, UNO_QUERY );
944 if ( xTrans.is() )
946 if ( lcl_storageIsWritable_nothrow( _rxStorage ) )
947 xTrans->commit();
948 bSuccess = true;
950 return bSuccess;
952 // -----------------------------------------------------------------------------
953 bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference< XStorage >& _rxStorage ) SAL_THROW(())
955 bool bSuccess = false;
958 bSuccess = commitStorageIfWriteable( _rxStorage );
960 catch( const Exception& )
962 DBG_UNHANDLED_EXCEPTION();
964 return bSuccess;
966 // -----------------------------------------------------------------------------
967 void ODatabaseModelImpl::setModified( sal_Bool _bModified )
969 if ( isModifyLocked() )
970 return;
974 Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY );
975 if ( xModi.is() )
976 xModi->setModified( _bModified );
977 else
978 m_bModified = _bModified;
980 catch( const Exception& )
982 DBG_UNHANDLED_EXCEPTION();
986 // -----------------------------------------------------------------------------
987 Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource()
989 Reference<XDataSource> xDs = m_xDataSource;
990 if ( !xDs.is() )
992 xDs = new ODatabaseSource(this);
993 m_xDataSource = xDs;
995 return xDs;
997 // -----------------------------------------------------------------------------
998 Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const
1000 return m_xModel;
1002 // -----------------------------------------------------------------------------
1003 Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize )
1005 Reference< XModel > xModel( m_xModel );
1006 OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" );
1007 if ( !xModel.is() )
1009 xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
1010 m_xModel = xModel;
1014 Reference< XSet > xModelCollection;
1015 if ( m_aContext.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection ) )
1016 xModelCollection->insert( makeAny( xModel ) );
1018 catch( const Exception& )
1020 DBG_UNHANDLED_EXCEPTION();
1023 if ( _bInitialize )
1027 Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
1028 xLoad->initNew();
1030 catch( RuntimeException& ) { throw; }
1031 catch( const Exception& )
1033 DBG_UNHANDLED_EXCEPTION();
1037 return xModel;
1039 // -----------------------------------------------------------------------------
1040 oslInterlockedCount SAL_CALL ODatabaseModelImpl::acquire()
1042 return osl_incrementInterlockedCount(&m_refCount);
1044 // -----------------------------------------------------------------------------
1045 oslInterlockedCount SAL_CALL ODatabaseModelImpl::release()
1047 if ( osl_decrementInterlockedCount(&m_refCount) == 0 )
1049 acquire(); // prevent multiple releases
1050 m_pDBContext->removeFromTerminateListener(*this);
1051 dispose();
1052 m_pDBContext->storeTransientProperties(*this);
1053 revokeDataSource();
1054 delete this;
1055 return 0;
1057 return m_refCount;
1059 // -----------------------------------------------------------------------------
1060 void ODatabaseModelImpl::commitStorages() SAL_THROW(( IOException, RuntimeException ))
1064 TStorages::iterator aIter = m_aStorages.begin();
1065 TStorages::iterator aEnd = m_aStorages.end();
1066 for (; aIter != aEnd ; ++aIter)
1067 commitStorageIfWriteable( aIter->second );
1069 catch(const WrappedTargetException&)
1071 // WrappedTargetException not allowed to leave
1072 throw IOException();
1076 // -----------------------------------------------------------------------------
1077 const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings()
1079 static const AsciiPropertyValue aKnownSettings[] =
1081 // known JDBC settings
1082 AsciiPropertyValue( "JavaDriverClass", makeAny( ::rtl::OUString() ) ),
1083 AsciiPropertyValue( "IgnoreCurrency", makeAny( (sal_Bool)sal_False ) ),
1084 // known settings for file-based drivers
1085 AsciiPropertyValue( "Extension", makeAny( ::rtl::OUString() ) ),
1086 AsciiPropertyValue( "CharSet", makeAny( ::rtl::OUString() ) ),
1087 AsciiPropertyValue( "HeaderLine", makeAny( (sal_Bool)sal_True ) ),
1088 AsciiPropertyValue( "FieldDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ) ),
1089 AsciiPropertyValue( "StringDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ) ) ),
1090 AsciiPropertyValue( "DecimalDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ),
1091 AsciiPropertyValue( "ThousandDelimiter", makeAny( ::rtl::OUString() ) ),
1092 AsciiPropertyValue( "ShowDeleted", makeAny( (sal_Bool)sal_False ) ),
1093 // known ODBC settings
1094 AsciiPropertyValue( "SystemDriverSettings", makeAny( ::rtl::OUString() ) ),
1095 AsciiPropertyValue( "UseCatalog", makeAny( (sal_Bool)sal_False ) ),
1096 AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence< Any >()) ),
1097 // settings related to auto increment handling
1098 AsciiPropertyValue( "AutoIncrementCreation", makeAny( ::rtl::OUString() ) ),
1099 AsciiPropertyValue( "AutoRetrievingStatement", makeAny( ::rtl::OUString() ) ),
1100 AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( (sal_Bool)sal_False ) ),
1101 // known Adabas D driver setting
1102 AsciiPropertyValue( "ShutdownDatabase", makeAny( (sal_Bool)sal_False ) ),
1103 AsciiPropertyValue( "DataCacheSizeIncrement", makeAny( (sal_Int32)20 ) ),
1104 AsciiPropertyValue( "DataCacheSize", makeAny( (sal_Int32)20 ) ),
1105 AsciiPropertyValue( "ControlUser", makeAny( ::rtl::OUString() ) ),
1106 AsciiPropertyValue( "ControlPassword", makeAny( ::rtl::OUString() ) ),
1107 // known LDAP driver settings
1108 AsciiPropertyValue( "HostName", makeAny( ::rtl::OUString() ) ),
1109 AsciiPropertyValue( "PortNumber", makeAny( (sal_Int32)389 ) ),
1110 AsciiPropertyValue( "BaseDN", makeAny( ::rtl::OUString() ) ),
1111 AsciiPropertyValue( "MaxRowCount", makeAny( (sal_Int32)100 ) ),
1112 // known MySQLNative driver settings
1113 AsciiPropertyValue( "LocalSocket", makeAny( ::rtl::OUString() ) ),
1114 // misc known driver settings
1115 AsciiPropertyValue( "ParameterNameSubstitution", makeAny( (sal_Bool)sal_False ) ),
1116 AsciiPropertyValue( "AddIndexAppendix", makeAny( (sal_Bool)sal_True ) ),
1117 AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( (sal_Bool)sal_True ) ),
1118 AsciiPropertyValue( "ImplicitCatalogRestriction", Any( ) ),
1119 AsciiPropertyValue( "ImplicitSchemaRestriction", Any( ) ),
1120 // known SDB level settings
1121 AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool)sal_False ) ),
1122 AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool)sal_False ) ),
1123 AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( (sal_Bool)sal_True ) ),
1124 AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( (sal_Bool)sal_True ) ),
1125 AsciiPropertyValue( "EnableSQL92Check", makeAny( (sal_Bool)sal_False ) ),
1126 AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER ) ),
1127 AsciiPropertyValue( "TableTypeFilterMode", makeAny( (sal_Int32)3 ) ),
1128 AsciiPropertyValue( "RespectDriverResultSetType", makeAny( (sal_Bool)sal_False ) ),
1129 AsciiPropertyValue( "UseSchemaInSelect", makeAny( (sal_Bool)sal_True ) ),
1130 AsciiPropertyValue( "UseCatalogInSelect", makeAny( (sal_Bool)sal_True ) ),
1131 AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( (sal_Bool)sal_True ) ),
1132 AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( (sal_Bool)sal_False ) ),
1133 AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( (sal_Bool)sal_True ) ),
1134 AsciiPropertyValue( "EscapeDateTime", makeAny( (sal_Bool)sal_True ) ),
1136 AsciiPropertyValue( NULL, Any() )
1138 return aKnownSettings;
1141 // -----------------------------------------------------------------------------
1142 TContentPtr& ODatabaseModelImpl::getObjectContainer( ObjectType _eType )
1144 OSL_PRECOND( _eType >= E_FORM && _eType <= E_TABLE, "ODatabaseModelImpl::getObjectContainer: illegal index!" );
1145 TContentPtr& rContentPtr = m_aContainer[ _eType ];
1147 if ( !rContentPtr.get() )
1149 rContentPtr = TContentPtr( new ODefinitionContainer_Impl );
1150 rContentPtr->m_pDataSource = this;
1151 rContentPtr->m_aProps.aTitle = lcl_getContainerStorageName_throw( _eType );
1153 return rContentPtr;
1156 // -----------------------------------------------------------------------------
1157 void ODatabaseModelImpl::revokeDataSource() const
1159 if ( m_pDBContext && m_sDocumentURL.getLength() )
1160 m_pDBContext->deregisterPrivate( m_sDocumentURL );
1163 // -----------------------------------------------------------------------------
1164 bool ODatabaseModelImpl::adjustMacroMode_AutoReject()
1166 return m_aMacroMode.adjustMacroMode( NULL );
1169 // -----------------------------------------------------------------------------
1170 bool ODatabaseModelImpl::checkMacrosOnLoading()
1172 ::comphelper::NamedValueCollection aArgs( m_aArgs );
1173 Reference< XInteractionHandler > xInteraction;
1174 xInteraction = aArgs.getOrDefault( "InteractionHandler", xInteraction );
1175 return m_aMacroMode.checkMacrosOnLoading( xInteraction );
1178 // -----------------------------------------------------------------------------
1179 void ODatabaseModelImpl::resetMacroExecutionMode()
1181 m_aMacroMode = ::sfx2::DocumentMacroMode( *this );
1184 // -----------------------------------------------------------------------------
1185 Reference< XStorageBasedLibraryContainer > ODatabaseModelImpl::getLibraryContainer( bool _bScript )
1187 Reference< XStorageBasedLibraryContainer >& rxContainer( _bScript ? m_xBasicLibraries : m_xDialogLibraries );
1188 if ( rxContainer.is() )
1189 return rxContainer;
1191 Reference< XStorageBasedDocument > xDocument( getModel_noCreate(), UNO_QUERY_THROW );
1192 // this is only to be called if there already exists a document model - in fact, it is
1193 // to be called by the document model only
1197 Reference< XStorageBasedLibraryContainer > (*Factory)( const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)
1198 = _bScript ? &DocumentScriptLibraryContainer::create : &DocumentDialogLibraryContainer::create;
1200 rxContainer.set(
1201 (*Factory)( m_aContext.getUNOContext(), xDocument ),
1202 UNO_QUERY_THROW
1205 catch( const RuntimeException& )
1207 throw;
1209 catch( const Exception& )
1211 throw WrappedTargetRuntimeException(
1212 ::rtl::OUString(),
1213 xDocument,
1214 ::cppu::getCaughtException()
1217 return rxContainer;
1220 // -----------------------------------------------------------------------------
1221 void ODatabaseModelImpl::storeLibraryContainersTo( const Reference< XStorage >& _rxToRootStorage )
1223 if ( m_xBasicLibraries.is() )
1224 m_xBasicLibraries->storeLibrariesToStorage( _rxToRootStorage );
1226 if ( m_xDialogLibraries.is() )
1227 m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage );
1230 // -----------------------------------------------------------------------------
1231 Reference< XStorage > ODatabaseModelImpl::switchToStorage( const Reference< XStorage >& _rxNewRootStorage )
1233 if ( !_rxNewRootStorage.is() )
1234 throw IllegalArgumentException();
1236 return impl_switchToStorage_throw( _rxNewRootStorage );
1239 // -----------------------------------------------------------------------------
1240 namespace
1242 void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument,
1243 const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener,
1244 ::vos::IMutex& _rMutex, bool _bListen )
1246 Reference< XModifiable > xModify( _rxStorage, UNO_QUERY );
1247 OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" );
1249 if ( xModify.is() && !_bListen && _inout_rListener.is() )
1251 xModify->removeModifyListener( _inout_rListener.get() );
1254 if ( _inout_rListener.is() )
1256 _inout_rListener->dispose();
1257 _inout_rListener = NULL;
1260 if ( xModify.is() && _bListen )
1262 _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex );
1263 xModify->addModifyListener( _inout_rListener.get() );
1268 // -----------------------------------------------------------------------------
1269 namespace
1271 static void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer,
1272 const Reference< XStorage >& _rxNewRootStorage )
1274 if ( _rxContainer.is() )
1276 if ( _rxNewRootStorage.is() )
1277 _rxContainer->setRootStorage( _rxNewRootStorage );
1278 // else
1279 // TODO: what to do here? dispose the container?
1284 // -----------------------------------------------------------------------------
1285 Reference< XStorage > ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage )
1287 // stop listening for modifications at the old storage
1288 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, false );
1290 // set new storage
1291 m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership );
1293 // start listening for modifications
1294 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, true );
1296 // forward new storage to Basic and Dialog library containers
1297 lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() );
1298 lcl_rebaseScriptStorage_throw( m_xDialogLibraries, m_xDocumentStorage.getTyped() );
1300 m_bReadOnly = !lcl_storageIsWritable_nothrow( m_xDocumentStorage.getTyped() );
1301 // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property
1303 return m_xDocumentStorage.getTyped();
1306 // -----------------------------------------------------------------------------
1307 void ODatabaseModelImpl::switchToURL( const ::rtl::OUString& _rDocumentLocation, const ::rtl::OUString& _rDocumentURL )
1309 // register at the database context, or change registration
1310 if ( _rDocumentURL != m_sDocumentURL )
1312 if ( m_pDBContext )
1314 if ( m_sDocumentURL.getLength() )
1315 m_pDBContext->nameChangePrivate( m_sDocumentURL, _rDocumentURL );
1316 else
1317 m_pDBContext->registerPrivate( _rDocumentURL, this );
1320 if ( ( m_sName == m_sDocumentURL ) // our name is our old URL
1321 || ( !m_sName.getLength() ) // we do not have a name, yet (i.e. are not registered at the database context)
1324 INetURLObject aURL( _rDocumentURL );
1325 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
1327 m_sName = _rDocumentURL;
1328 // TODO: our data source must broadcast the change of the Name property
1333 // remember both
1334 m_sDocFileLocation = _rDocumentLocation.getLength() ? _rDocumentLocation : _rDocumentURL;
1335 m_sDocumentURL = _rDocumentURL;
1338 // -----------------------------------------------------------------------------
1339 bool ODatabaseModelImpl::isDatabaseStorage( const Reference< XStorage >& _rxStorage ) const
1341 TStorages::const_iterator pos = m_aStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
1342 if ( ( pos != m_aStorages.end() )
1343 && ( pos->second == _rxStorage )
1346 return true;
1348 return false;
1351 // -----------------------------------------------------------------------------
1352 ::rtl::OUString ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType )
1354 return lcl_getContainerStorageName_throw( _eType );
1357 // -----------------------------------------------------------------------------
1358 sal_Int16 ODatabaseModelImpl::getCurrentMacroExecMode() const
1360 sal_Int16 nCurrentMode = MacroExecMode::NEVER_EXECUTE;
1363 ::comphelper::NamedValueCollection aArgs( m_aArgs );
1364 nCurrentMode = aArgs.getOrDefault( "MacroExecutionMode", nCurrentMode );
1366 catch( const Exception& )
1368 DBG_UNHANDLED_EXCEPTION();
1370 return nCurrentMode;
1373 // -----------------------------------------------------------------------------
1374 sal_Bool ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1378 ::comphelper::NamedValueCollection aArgs( m_aArgs );
1379 aArgs.put( "MacroExecutionMode", nMacroMode );
1380 aArgs >>= m_aArgs;
1381 return sal_True;
1383 catch( const Exception& )
1385 DBG_UNHANDLED_EXCEPTION();
1388 return sal_False;
1391 // -----------------------------------------------------------------------------
1392 ::rtl::OUString ODatabaseModelImpl::getDocumentLocation() const
1394 // don't return getURL() (or m_sDocumentURL, which is the same). In case we were recovered
1395 // after a previous crash of OOo, m_sDocFileLocation points to the file which were loaded from,
1396 // and this is the one we need for security checks.
1397 return getDocFileLocation();
1400 // -----------------------------------------------------------------------------
1401 Reference< XStorage > ODatabaseModelImpl::getLastCommitDocumentStorage()
1403 // we do not support signing the scripting storages, so we're allowed to
1404 // return <NULL/> here.
1405 return Reference< XStorage >();
1408 // -----------------------------------------------------------------------------
1409 ODatabaseModelImpl::EmbeddedMacros ODatabaseModelImpl::determineEmbeddedMacros()
1411 if ( !m_aEmbeddedMacros )
1413 if ( ::sfx2::DocumentMacroMode::storageHasMacros( const_cast< ODatabaseModelImpl* >( this )->getOrCreateRootStorage() ) )
1415 m_aEmbeddedMacros.reset( eDocumentWideMacros );
1417 else if ( lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_FORM )
1418 || lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_REPORT )
1421 m_aEmbeddedMacros.reset( eSubDocumentMacros );
1423 else
1425 m_aEmbeddedMacros.reset( eNoMacros );
1428 return *m_aEmbeddedMacros;
1431 // -----------------------------------------------------------------------------
1432 sal_Bool ODatabaseModelImpl::documentStorageHasMacros() const
1434 const_cast< ODatabaseModelImpl* >( this )->determineEmbeddedMacros();
1435 return ( *m_aEmbeddedMacros != eNoMacros );
1438 // -----------------------------------------------------------------------------
1439 Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const
1441 return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY );
1444 // -----------------------------------------------------------------------------
1445 sal_Int16 ODatabaseModelImpl::getScriptingSignatureState() const
1447 // no support for signatures at the moment
1448 return SIGNATURESTATE_NOSIGNATURES;
1451 // -----------------------------------------------------------------------------
1452 void ODatabaseModelImpl::showBrokenSignatureWarning( const Reference< XInteractionHandler >& /*_rxInteraction*/ ) const
1454 OSL_ENSURE( false, "ODatabaseModelImpl::showBrokenSignatureWarning: signatures can't be broken - we do not support them!" );
1457 // -----------------------------------------------------------------------------
1458 void ODatabaseModelImpl::storageIsModified()
1460 setModified( sal_True );
1463 // -----------------------------------------------------------------------------
1464 ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model )
1465 :m_pImpl( _model )
1466 ,m_aMutex( _model->getSharedMutex() )
1470 // -----------------------------------------------------------------------------
1471 ModelDependentComponent::~ModelDependentComponent()
1475 //........................................................................
1476 } // namespace dbaccess
1477 //........................................................................