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 :
21 : #include "commandcontainer.hxx"
22 : #include "connection.hxx"
23 : #include "core_resource.hrc"
24 : #include "core_resource.hxx"
25 : #include "databasecontext.hxx"
26 : #include "databasedocument.hxx"
27 : #include "datasource.hxx"
28 : #include "dbastrings.hrc"
29 : #include "ModelImpl.hxx"
30 : #include "userinformation.hxx"
31 : #include "sdbcoretools.hxx"
32 :
33 : #include <com/sun/star/container/XSet.hpp>
34 : #include <com/sun/star/document/MacroExecMode.hpp>
35 : #include <com/sun/star/frame/GlobalEventBroadcaster.hpp>
36 : #include <com/sun/star/embed/XTransactedObject.hpp>
37 : #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
38 : #include <com/sun/star/embed/StorageFactory.hpp>
39 : #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
40 : #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
41 : #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
42 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
43 : #include <com/sun/star/form/XLoadable.hpp>
44 : #include <com/sun/star/util/NumberFormatsSupplier.hpp>
45 :
46 : #include <comphelper/interaction.hxx>
47 : #include <comphelper/mediadescriptor.hxx>
48 : #include <comphelper/seqstream.hxx>
49 : #include <comphelper/sequence.hxx>
50 : #include <connectivity/dbexception.hxx>
51 : #include <cppuhelper/exc_hlp.hxx>
52 : #include <cppuhelper/typeprovider.hxx>
53 : #include <rtl/digest.h>
54 : #include <sfx2/signaturestate.hxx>
55 : #include <tools/debug.hxx>
56 : #include <tools/diagnose_ex.h>
57 : #include <osl/diagnose.h>
58 : #include <tools/errcode.hxx>
59 : #include <tools/urlobj.hxx>
60 : #include <unotools/sharedunocomponent.hxx>
61 :
62 : #include <algorithm>
63 :
64 : using namespace ::com::sun::star::document;
65 : using namespace ::com::sun::star::sdbc;
66 : using namespace ::com::sun::star::sdbcx;
67 : using namespace ::com::sun::star::sdb;
68 : using namespace ::com::sun::star::beans;
69 : using namespace ::com::sun::star::uno;
70 : using namespace ::com::sun::star::lang;
71 : using namespace ::com::sun::star::embed;
72 : using namespace ::com::sun::star::container;
73 : using namespace ::com::sun::star::util;
74 : using namespace ::com::sun::star::io;
75 : using namespace ::com::sun::star::task;
76 : using namespace ::com::sun::star::ucb;
77 : using namespace ::com::sun::star::frame;
78 : using namespace ::com::sun::star::view;
79 : using namespace ::com::sun::star::task;
80 : using namespace ::com::sun::star::reflection;
81 : using namespace ::com::sun::star::script;
82 : using namespace ::cppu;
83 : using namespace ::osl;
84 : using namespace ::dbtools;
85 : using namespace ::comphelper;
86 :
87 : namespace dbaccess
88 : {
89 :
90 : //============================================================
91 : //= VosMutexFacade
92 : //============================================================
93 0 : VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex )
94 0 : :m_rMutex( _rMutex )
95 : {
96 0 : }
97 :
98 0 : void SAL_CALL VosMutexFacade::acquire()
99 : {
100 0 : m_rMutex.acquire();
101 0 : }
102 :
103 0 : sal_Bool SAL_CALL VosMutexFacade::tryToAcquire()
104 : {
105 0 : return m_rMutex.tryToAcquire();
106 : }
107 :
108 0 : void SAL_CALL VosMutexFacade::release()
109 : {
110 0 : m_rMutex.release();
111 0 : }
112 :
113 : //============================================================
114 : //= DocumentStorageAccess
115 : //============================================================
116 : DBG_NAME( DocumentStorageAccess )
117 : class DocumentStorageAccess : public ::cppu::WeakImplHelper2< XDocumentSubStorageSupplier
118 : , XTransactionListener >
119 : {
120 : typedef ::std::map< ::rtl::OUString, Reference< XStorage > > NamedStorages;
121 :
122 : ::osl::Mutex m_aMutex;
123 : /// all sub storages which we ever gave to the outer world
124 : NamedStorages m_aExposedStorages;
125 : ODatabaseModelImpl* m_pModelImplementation;
126 : bool m_bPropagateCommitToRoot;
127 : bool m_bDisposingSubStorages;
128 :
129 : public:
130 0 : DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation )
131 : :m_pModelImplementation( &_rModelImplementation )
132 : ,m_bPropagateCommitToRoot( true )
133 0 : ,m_bDisposingSubStorages( false )
134 : {
135 : DBG_CTOR( DocumentStorageAccess, NULL );
136 0 : }
137 :
138 : protected:
139 0 : ~DocumentStorageAccess()
140 0 : {
141 : DBG_DTOR( DocumentStorageAccess, NULL );
142 0 : }
143 :
144 : public:
145 : void dispose();
146 :
147 : // XDocumentSubStorageSupplier
148 : virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nMode ) throw (RuntimeException);
149 : virtual Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (IOException, RuntimeException);
150 :
151 : // XTransactionListener
152 : virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
153 : virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
154 : virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
155 : virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
156 :
157 : // XEventListener
158 : virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
159 :
160 : /// disposes all storages managed by this instance
161 : void disposeStorages();
162 :
163 : /// disposes all known sub storages
164 : void commitStorages() SAL_THROW(( IOException, RuntimeException ));
165 :
166 : /// commits the dedicated "database" storage
167 : bool commitEmbeddedStorage( bool _bPreventRootCommits );
168 :
169 : private:
170 : /** opens the sub storage with the given name, in the given mode
171 : */
172 : Reference< XStorage > impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nMode );
173 :
174 0 : void impl_suspendCommitPropagation()
175 : {
176 : OSL_ENSURE( m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_suspendCommitPropagation: already suspended" );
177 0 : m_bPropagateCommitToRoot = false;
178 0 : }
179 0 : void impl_resumeCommitPropagation()
180 : {
181 : OSL_ENSURE( !m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_resumeCommitPropagation: not suspended" );
182 0 : m_bPropagateCommitToRoot = true;
183 0 : }
184 :
185 : };
186 :
187 0 : void DocumentStorageAccess::dispose()
188 : {
189 0 : ::osl::MutexGuard aGuard( m_aMutex );
190 :
191 0 : for ( NamedStorages::iterator loop = m_aExposedStorages.begin();
192 0 : loop != m_aExposedStorages.end();
193 : ++loop
194 : )
195 : {
196 : try
197 : {
198 0 : Reference< XTransactionBroadcaster > xBroadcaster( loop->second, UNO_QUERY );
199 0 : if ( xBroadcaster.is() )
200 0 : xBroadcaster->removeTransactionListener( this );
201 : }
202 0 : catch( const Exception& )
203 : {
204 : DBG_UNHANDLED_EXCEPTION();
205 : }
206 : }
207 :
208 0 : m_aExposedStorages.clear();
209 :
210 0 : m_pModelImplementation = NULL;
211 0 : }
212 :
213 0 : Reference< XStorage > DocumentStorageAccess::impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nDesiredMode )
214 : {
215 : OSL_ENSURE( !_rStorageName.isEmpty(),"ODatabaseModelImpl::impl_openSubStorage_nothrow: Invalid storage name!" );
216 :
217 0 : Reference< XStorage > xStorage;
218 : try
219 : {
220 0 : Reference< XStorage > xRootStorage( m_pModelImplementation->getOrCreateRootStorage() );
221 0 : if ( xRootStorage.is() )
222 : {
223 0 : sal_Int32 nRealMode = m_pModelImplementation->m_bDocumentReadOnly ? ElementModes::READ : _nDesiredMode;
224 0 : if ( nRealMode == ElementModes::READ )
225 : {
226 0 : Reference< XNameAccess > xSubStorageNames( xRootStorage, UNO_QUERY );
227 0 : if ( xSubStorageNames.is() && !xSubStorageNames->hasByName( _rStorageName ) )
228 0 : return xStorage;
229 : }
230 :
231 0 : xStorage = xRootStorage->openStorageElement( _rStorageName, nRealMode );
232 :
233 0 : Reference< XTransactionBroadcaster > xBroad( xStorage, UNO_QUERY );
234 0 : if ( xBroad.is() )
235 0 : xBroad->addTransactionListener( this );
236 0 : }
237 : }
238 0 : catch( const Exception& )
239 : {
240 : DBG_UNHANDLED_EXCEPTION();
241 : }
242 :
243 0 : return xStorage;
244 : }
245 :
246 0 : void DocumentStorageAccess::disposeStorages()
247 : {
248 0 : m_bDisposingSubStorages = true;
249 :
250 0 : NamedStorages::iterator aEnd = m_aExposedStorages.end();
251 0 : for ( NamedStorages::iterator aIter = m_aExposedStorages.begin();
252 : aIter != aEnd ;
253 : ++aIter
254 : )
255 : {
256 : try
257 : {
258 0 : ::comphelper::disposeComponent( aIter->second );
259 : }
260 0 : catch( const Exception& )
261 : {
262 : DBG_UNHANDLED_EXCEPTION();
263 : }
264 : }
265 0 : m_aExposedStorages.clear();
266 :
267 0 : m_bDisposingSubStorages = false;
268 0 : }
269 :
270 0 : void DocumentStorageAccess::commitStorages() SAL_THROW(( IOException, RuntimeException ))
271 : {
272 : try
273 : {
274 0 : for ( NamedStorages::const_iterator aIter = m_aExposedStorages.begin();
275 0 : aIter != m_aExposedStorages.end();
276 : ++aIter
277 : )
278 : {
279 0 : tools::stor::commitStorageIfWriteable( aIter->second );
280 : }
281 : }
282 0 : catch(const WrappedTargetException&)
283 : {
284 : // WrappedTargetException not allowed to leave
285 0 : throw IOException();
286 : }
287 0 : }
288 :
289 0 : bool DocumentStorageAccess::commitEmbeddedStorage( bool _bPreventRootCommits )
290 : {
291 0 : if ( _bPreventRootCommits )
292 0 : impl_suspendCommitPropagation();
293 :
294 0 : bool bSuccess = false;
295 : try
296 : {
297 0 : NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
298 0 : if ( pos != m_aExposedStorages.end() )
299 0 : bSuccess = tools::stor::commitStorageIfWriteable( pos->second );
300 : }
301 0 : catch( Exception& )
302 : {
303 : DBG_UNHANDLED_EXCEPTION();
304 : }
305 :
306 0 : if ( _bPreventRootCommits )
307 0 : impl_resumeCommitPropagation();
308 :
309 0 : return bSuccess;
310 :
311 : }
312 :
313 0 : Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nDesiredMode ) throw (RuntimeException)
314 : {
315 0 : ::osl::MutexGuard aGuard( m_aMutex );
316 0 : NamedStorages::iterator pos = m_aExposedStorages.find( aStorageName );
317 0 : if ( pos == m_aExposedStorages.end() )
318 : {
319 0 : Reference< XStorage > xResult = impl_openSubStorage_nothrow( aStorageName, _nDesiredMode );
320 0 : pos = m_aExposedStorages.insert( NamedStorages::value_type( aStorageName, xResult ) ).first;
321 : }
322 :
323 0 : return pos->second;
324 : }
325 :
326 0 : Sequence< ::rtl::OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (IOException, RuntimeException)
327 : {
328 0 : Reference< XStorage > xRootStor( m_pModelImplementation->getRootStorage() );
329 0 : if ( !xRootStor.is() )
330 0 : return Sequence< ::rtl::OUString >();
331 :
332 0 : ::std::vector< ::rtl::OUString > aNames;
333 :
334 0 : Reference< XNameAccess > xNames( xRootStor, UNO_QUERY_THROW );
335 0 : Sequence< ::rtl::OUString > aElementNames( xNames->getElementNames() );
336 0 : for ( sal_Int32 i=0; i<aElementNames.getLength(); ++i )
337 : {
338 0 : if ( xRootStor->isStorageElement( aElementNames[i] ) )
339 0 : aNames.push_back( aElementNames[i] );
340 : }
341 0 : return aNames.empty()
342 : ? Sequence< ::rtl::OUString >()
343 0 : : Sequence< ::rtl::OUString >( &aNames[0], aNames.size() );
344 : }
345 :
346 0 : void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
347 : {
348 : // not interested in
349 0 : }
350 :
351 0 : void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent ) throw (RuntimeException)
352 : {
353 0 : ::osl::MutexGuard aGuard( m_aMutex );
354 :
355 0 : if ( m_pModelImplementation )
356 0 : m_pModelImplementation->setModified( sal_True );
357 :
358 0 : if ( m_pModelImplementation && m_bPropagateCommitToRoot )
359 : {
360 0 : Reference< XStorage > xStorage( aEvent.Source, UNO_QUERY );
361 :
362 : // check if this is the dedicated "database" sub storage
363 0 : NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
364 0 : if ( ( pos != m_aExposedStorages.end() )
365 0 : && ( pos->second == xStorage )
366 : )
367 : {
368 : // if so, also commit the root storage
369 0 : m_pModelImplementation->commitRootStorage();
370 0 : }
371 0 : }
372 0 : }
373 :
374 0 : void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException)
375 : {
376 : // not interested in
377 0 : }
378 :
379 0 : void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& /*aEvent*/ ) throw (RuntimeException)
380 : {
381 : // not interested in
382 0 : }
383 :
384 0 : void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source ) throw ( RuntimeException )
385 : {
386 : OSL_ENSURE( Reference< XStorage >( Source.Source, UNO_QUERY ).is(), "DocumentStorageAccess::disposing: No storage? What's this?" );
387 :
388 0 : if ( m_bDisposingSubStorages )
389 0 : return;
390 :
391 0 : for ( NamedStorages::iterator find = m_aExposedStorages.begin();
392 0 : find != m_aExposedStorages.end();
393 : ++find
394 : )
395 0 : if ( find->second == Source.Source )
396 : {
397 0 : m_aExposedStorages.erase( find );
398 0 : break;
399 : }
400 : }
401 :
402 : //============================================================
403 : //= ODatabaseModelImpl
404 : //============================================================
405 : DBG_NAME(ODatabaseModelImpl)
406 :
407 0 : ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >& _rxFactory, ODatabaseContext& _rDBContext )
408 : :m_xModel()
409 : ,m_xDataSource()
410 : ,m_pStorageAccess( NULL )
411 : ,m_aMutex()
412 : ,m_aMutexFacade( m_aMutex )
413 : ,m_aContainer(4)
414 : ,m_aMacroMode( *this )
415 : ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
416 : ,m_pDBContext( &_rDBContext )
417 : ,m_refCount(0)
418 : ,m_aEmbeddedMacros()
419 : ,m_bModificationLock( false )
420 : ,m_bDocumentInitialized( false )
421 : ,m_aContext( _rxFactory )
422 : ,m_nLoginTimeout(0)
423 : ,m_bReadOnly(sal_False)
424 : ,m_bPasswordRequired(sal_False)
425 : ,m_bSuppressVersionColumns(sal_True)
426 : ,m_bModified(sal_False)
427 : ,m_bDocumentReadOnly(sal_False)
428 : ,m_pSharedConnectionManager(NULL)
429 0 : ,m_nControllerLockCount(0)
430 : {
431 : // some kind of default
432 : DBG_CTOR(ODatabaseModelImpl,NULL);
433 0 : m_sConnectURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jdbc:"));
434 0 : m_aTableFilter.realloc(1);
435 0 : m_aTableFilter[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%"));
436 0 : impl_construct_nothrow();
437 0 : }
438 :
439 0 : ODatabaseModelImpl::ODatabaseModelImpl(
440 : const ::rtl::OUString& _rRegistrationName,
441 : const Reference< XMultiServiceFactory >& _rxFactory,
442 : ODatabaseContext& _rDBContext
443 : )
444 : :m_xModel()
445 : ,m_xDataSource()
446 : ,m_pStorageAccess( NULL )
447 : ,m_aMutex()
448 : ,m_aMutexFacade( m_aMutex )
449 : ,m_aContainer(4)
450 : ,m_aMacroMode( *this )
451 : ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
452 : ,m_pDBContext( &_rDBContext )
453 : ,m_refCount(0)
454 : ,m_aEmbeddedMacros()
455 : ,m_bModificationLock( false )
456 : ,m_bDocumentInitialized( false )
457 : ,m_aContext( _rxFactory )
458 : ,m_sName(_rRegistrationName)
459 : ,m_nLoginTimeout(0)
460 : ,m_bReadOnly(sal_False)
461 : ,m_bPasswordRequired(sal_False)
462 : ,m_bSuppressVersionColumns(sal_True)
463 : ,m_bModified(sal_False)
464 : ,m_bDocumentReadOnly(sal_False)
465 : ,m_pSharedConnectionManager(NULL)
466 0 : ,m_nControllerLockCount(0)
467 : {
468 : DBG_CTOR(ODatabaseModelImpl,NULL);
469 0 : impl_construct_nothrow();
470 0 : }
471 :
472 0 : ODatabaseModelImpl::~ODatabaseModelImpl()
473 : {
474 : DBG_DTOR(ODatabaseModelImpl,NULL);
475 0 : }
476 :
477 0 : void ODatabaseModelImpl::impl_construct_nothrow()
478 : {
479 : // create the property bag to hold the settings (also known as "Info" property)
480 : try
481 : {
482 : // the set of property value types in the bag is limited:
483 0 : Sequence< Type > aAllowedTypes(6);
484 0 : Type* pAllowedType = aAllowedTypes.getArray();
485 0 : *pAllowedType++ = ::getCppuType( static_cast< sal_Bool* >( NULL ) );
486 0 : *pAllowedType++ = ::getCppuType( static_cast< double* >( NULL ) );
487 0 : *pAllowedType++ = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
488 0 : *pAllowedType++ = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
489 0 : *pAllowedType++ = ::getCppuType( static_cast< sal_Int16* >( NULL ) );
490 0 : *pAllowedType++ = ::getCppuType( static_cast< Sequence< Any >* >( NULL ) );
491 :
492 0 : Sequence< Any > aInitArgs( 2 );
493 0 : aInitArgs[0] <<= NamedValue(
494 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutomaticAddition" ) ),
495 : makeAny( (sal_Bool)sal_True )
496 0 : );
497 0 : aInitArgs[1] <<= NamedValue(
498 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowedTypes" ) ),
499 : makeAny( aAllowedTypes )
500 0 : );
501 :
502 0 : m_xSettings.set( m_aContext.createComponentWithArguments( "com.sun.star.beans.PropertyBag", aInitArgs ), UNO_QUERY_THROW );
503 :
504 : // insert the default settings
505 0 : Reference< XPropertyContainer > xContainer( m_xSettings, UNO_QUERY_THROW );
506 0 : Reference< XSet > xSettingsSet( m_xSettings, UNO_QUERY_THROW );
507 0 : const AsciiPropertyValue* pSettings = getDefaultDataSourceSettings();
508 0 : for ( ; pSettings->AsciiName; ++pSettings )
509 : {
510 0 : if ( !pSettings->DefaultValue.hasValue() )
511 : {
512 : Property aProperty(
513 : ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
514 : -1,
515 : pSettings->ValueType,
516 : PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID
517 0 : );
518 0 : xSettingsSet->insert( makeAny( aProperty ) );
519 : }
520 : else
521 : {
522 0 : xContainer->addProperty(
523 : ::rtl::OUString::createFromAscii( pSettings->AsciiName ),
524 : PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT,
525 : pSettings->DefaultValue
526 0 : );
527 : }
528 0 : }
529 : }
530 0 : catch( const Exception& )
531 : {
532 : DBG_UNHANDLED_EXCEPTION();
533 : }
534 0 : m_pDBContext->appendAtTerminateListener(*this);
535 0 : }
536 :
537 : namespace
538 : {
539 0 : ::rtl::OUString lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType )
540 : {
541 0 : const sal_Char* pAsciiName( NULL );
542 0 : switch ( _eType )
543 : {
544 0 : case ODatabaseModelImpl::E_FORM: pAsciiName = "forms"; break;
545 0 : case ODatabaseModelImpl::E_REPORT: pAsciiName = "reports"; break;
546 0 : case ODatabaseModelImpl::E_QUERY: pAsciiName = "queries"; break;
547 0 : case ODatabaseModelImpl::E_TABLE: pAsciiName = "tables"; break;
548 : default:
549 0 : throw RuntimeException();
550 : }
551 0 : return ::rtl::OUString::createFromAscii( pAsciiName );
552 : }
553 :
554 0 : bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl& _rObjectDefinitions, const Reference< XStorage >& _rxContainerStorage )
555 : {
556 0 : bool bSomeDocHasMacros = false;
557 :
558 0 : for ( ODefinitionContainer_Impl::const_iterator object = _rObjectDefinitions.begin();
559 0 : ( object != _rObjectDefinitions.end() ) && !bSomeDocHasMacros;
560 : ++object
561 : )
562 : {
563 : #if OSL_DEBUG_LEVEL > 0
564 : const ::rtl::OUString& rName( object->first ); (void)rName;
565 : #endif
566 :
567 0 : const TContentPtr& rDefinition( object->second );
568 0 : const ::rtl::OUString& rPersistentName( rDefinition->m_aProps.sPersistentName );
569 :
570 0 : if ( rPersistentName.isEmpty() )
571 : { // it's a logical sub folder used to organize the real objects
572 0 : const ODefinitionContainer_Impl& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl& >( *rDefinition.get() ) );
573 0 : bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions, _rxContainerStorage );
574 0 : continue;
575 : }
576 :
577 0 : bSomeDocHasMacros = ODatabaseModelImpl::objectHasMacros( _rxContainerStorage, rPersistentName );
578 : }
579 0 : return bSomeDocHasMacros;
580 : }
581 :
582 0 : bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl& _rModel, const ODatabaseModelImpl::ObjectType _eType )
583 : {
584 0 : bool bSomeDocHasMacros = false;
585 :
586 0 : const OContentHelper_Impl& rContainerData( *_rModel.getObjectContainer( _eType ).get() );
587 0 : const ODefinitionContainer_Impl& rObjectDefinitions = dynamic_cast< const ODefinitionContainer_Impl& >( rContainerData );
588 :
589 : try
590 : {
591 0 : Reference< XStorage > xContainerStorage( _rModel.getStorage( _eType, ElementModes::READWRITE ) );
592 : // note the READWRITE here: If the storage already existed before, then the OpenMode will
593 : // be ignored, anyway.
594 : // If the storage did not yet exist, then it will be created. If the database document
595 : // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise,
596 : // the storage will in fact be created as READWRITE. While this is not strictly necessary
597 : // for this particular use case here, it is required since the storage is *cached*, and
598 : // later use cases will need the READWRITE mode.
599 :
600 0 : if ( xContainerStorage.is() )
601 0 : bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rObjectDefinitions, xContainerStorage );
602 : }
603 0 : catch( const Exception& )
604 : {
605 : DBG_UNHANDLED_EXCEPTION();
606 : // be on the safe side: If we can't reliably determine whether there are macros,
607 : // assume there actually are. Better this way, than the other way round.
608 0 : bSomeDocHasMacros = true;
609 : }
610 :
611 0 : return bSomeDocHasMacros;
612 : }
613 : }
614 :
615 0 : bool ODatabaseModelImpl::objectHasMacros( const Reference< XStorage >& _rxContainerStorage, const ::rtl::OUString& _rPersistentName )
616 : {
617 : OSL_PRECOND( _rxContainerStorage.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" );
618 :
619 0 : bool bHasMacros = true;
620 : try
621 : {
622 0 : if ( !_rxContainerStorage->hasByName( _rPersistentName ) )
623 0 : return false;
624 :
625 0 : Reference< XStorage > xObjectStor( _rxContainerStorage->openStorageElement(
626 0 : _rPersistentName, ElementModes::READ ) );
627 :
628 0 : bHasMacros = ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor );
629 : }
630 0 : catch( const Exception& )
631 : {
632 : DBG_UNHANDLED_EXCEPTION();
633 : }
634 0 : return bHasMacros;
635 : }
636 :
637 0 : void ODatabaseModelImpl::reset()
638 : {
639 0 : m_bReadOnly = sal_False;
640 0 : ::std::vector< TContentPtr > aEmptyContainers( 4 );
641 0 : m_aContainer.swap( aEmptyContainers );
642 :
643 0 : if ( m_pStorageAccess )
644 : {
645 0 : m_pStorageAccess->dispose();
646 0 : m_pStorageAccess->release();
647 0 : m_pStorageAccess = NULL;
648 0 : }
649 0 : }
650 :
651 0 : void SAL_CALL ODatabaseModelImpl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
652 : {
653 0 : Reference<XConnection> xCon(Source.Source,UNO_QUERY);
654 0 : if ( xCon.is() )
655 : {
656 0 : bool bStore = false;
657 0 : OWeakConnectionArray::iterator aEnd = m_aConnections.end();
658 0 : for (OWeakConnectionArray::iterator i = m_aConnections.begin(); aEnd != i; ++i)
659 : {
660 0 : if ( xCon == i->get() )
661 : {
662 0 : *i = OWeakConnection();
663 0 : bStore = true;
664 0 : break;
665 : }
666 : }
667 :
668 0 : if ( bStore )
669 0 : commitRootStorage();
670 : }
671 : else
672 : {
673 : OSL_FAIL( "ODatabaseModelImpl::disposing: where does this come from?" );
674 0 : }
675 0 : }
676 :
677 0 : void ODatabaseModelImpl::clearConnections()
678 : {
679 0 : OWeakConnectionArray aConnections;
680 0 : aConnections.swap( m_aConnections );
681 :
682 0 : Reference< XConnection > xConn;
683 0 : OWeakConnectionArray::iterator aEnd = aConnections.end();
684 0 : for ( OWeakConnectionArray::iterator i = aConnections.begin(); aEnd != i; ++i )
685 : {
686 0 : xConn = *i;
687 0 : if ( xConn.is() )
688 : {
689 : try
690 : {
691 0 : xConn->close();
692 : }
693 0 : catch(const Exception&)
694 : {
695 : DBG_UNHANDLED_EXCEPTION();
696 : }
697 : }
698 : }
699 :
700 0 : m_pSharedConnectionManager = NULL;
701 0 : m_xSharedConnectionManager = NULL;
702 0 : }
703 :
704 0 : void ODatabaseModelImpl::dispose()
705 : {
706 : // dispose the data source and the model
707 : try
708 : {
709 0 : Reference< XDataSource > xDS( m_xDataSource );
710 0 : ::comphelper::disposeComponent( xDS );
711 :
712 0 : Reference< XModel > xModel( m_xModel );
713 0 : ::comphelper::disposeComponent( xModel );
714 : }
715 0 : catch( const Exception& )
716 : {
717 : DBG_UNHANDLED_EXCEPTION();
718 : }
719 0 : m_xDataSource = WeakReference<XDataSource>();
720 0 : m_xModel = WeakReference< XModel >();
721 :
722 0 : ::std::vector<TContentPtr>::iterator aIter = m_aContainer.begin();
723 0 : ::std::vector<TContentPtr>::iterator aEnd = m_aContainer.end();
724 0 : for (;aIter != aEnd ; ++aIter)
725 : {
726 0 : if ( aIter->get() )
727 0 : (*aIter)->m_pDataSource = NULL;
728 : }
729 0 : m_aContainer.clear();
730 :
731 0 : clearConnections();
732 :
733 0 : m_xNumberFormatsSupplier = NULL;
734 :
735 : try
736 : {
737 0 : sal_Bool bCouldStore = commitEmbeddedStorage( true );
738 : // "true" means that committing the embedded storage should not trigger committing the root
739 : // storage. This is because we are going to commit the root storage ourself, anyway
740 0 : disposeStorages();
741 0 : if ( bCouldStore )
742 0 : commitRootStorage();
743 :
744 0 : impl_switchToStorage_throw( NULL );
745 : }
746 0 : catch( const Exception& )
747 : {
748 : DBG_UNHANDLED_EXCEPTION();
749 : }
750 :
751 0 : if ( m_pStorageAccess )
752 : {
753 0 : m_pStorageAccess->dispose();
754 0 : m_pStorageAccess->release();
755 0 : m_pStorageAccess = NULL;
756 : }
757 0 : }
758 :
759 0 : const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormatsSupplier()
760 : {
761 0 : if (!m_xNumberFormatsSupplier.is())
762 : {
763 : // the arguments : the locale of the current user
764 0 : UserInformation aUserInfo;
765 0 : Locale aLocale = aUserInfo.getUserLanguage();
766 :
767 0 : m_xNumberFormatsSupplier.set( NumberFormatsSupplier::createWithLocale( m_aContext.getUNOContext(), aLocale ) );
768 : }
769 0 : return m_xNumberFormatsSupplier;
770 : }
771 :
772 0 : void ODatabaseModelImpl::setDocFileLocation( const ::rtl::OUString& i_rLoadedFrom )
773 : {
774 0 : ENSURE_OR_THROW( !i_rLoadedFrom.isEmpty(), "invalid URL" );
775 0 : m_sDocFileLocation = i_rLoadedFrom;
776 0 : }
777 :
778 0 : void ODatabaseModelImpl::setResource( const ::rtl::OUString& i_rDocumentURL, const Sequence< PropertyValue >& _rArgs )
779 : {
780 0 : ENSURE_OR_THROW( !i_rDocumentURL.isEmpty(), "invalid URL" );
781 :
782 0 : ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs );
783 : #if OSL_DEBUG_LEVEL > 0
784 : if ( aMediaDescriptor.has( "SalvagedFile" ) )
785 : {
786 : ::rtl::OUString sSalvagedFile( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) );
787 : // If SalvagedFile is an empty string, this indicates "the document is being recovered, but i_rDocumentURL already
788 : // is the real document URL, not the temporary document location"
789 : if ( sSalvagedFile.isEmpty() )
790 : sSalvagedFile = i_rDocumentURL;
791 :
792 : OSL_ENSURE( sSalvagedFile == i_rDocumentURL, "ODatabaseModelImpl::setResource: inconsistency!" );
793 : // nowadays, setResource should only be called with the logical URL of the document
794 : }
795 : #endif
796 :
797 0 : m_aMediaDescriptor = stripLoadArguments( aMediaDescriptor );
798 :
799 0 : impl_switchToLogicalURL( i_rDocumentURL );
800 0 : }
801 :
802 0 : ::comphelper::NamedValueCollection ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments )
803 : {
804 : OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" );
805 : OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" );
806 :
807 0 : ::comphelper::NamedValueCollection aMutableArgs( _rArguments );
808 0 : aMutableArgs.remove( "Model" );
809 0 : aMutableArgs.remove( "ViewName" );
810 0 : return aMutableArgs;
811 : }
812 :
813 0 : void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
814 : {
815 0 : getDocumentStorageAccess()->disposeStorages();
816 0 : }
817 :
818 0 : Reference< XSingleServiceFactory > ODatabaseModelImpl::createStorageFactory() const
819 : {
820 0 : return StorageFactory::create( m_aContext.getUNOContext() );
821 : }
822 :
823 0 : void ODatabaseModelImpl::commitRootStorage()
824 : {
825 0 : Reference< XStorage > xStorage( getOrCreateRootStorage() );
826 : #if OSL_DEBUG_LEVEL > 0
827 : bool bSuccess =
828 : #endif
829 0 : commitStorageIfWriteable_ignoreErrors( xStorage );
830 : OSL_ENSURE( bSuccess || !xStorage.is(),
831 0 : "ODatabaseModelImpl::commitRootStorage: could commit the storage!" );
832 0 : }
833 :
834 0 : Reference< XStorage > ODatabaseModelImpl::getOrCreateRootStorage()
835 : {
836 0 : if ( !m_xDocumentStorage.is() )
837 : {
838 0 : Reference< XSingleServiceFactory> xStorageFactory = StorageFactory::create( m_aContext.getUNOContext() );
839 0 : Any aSource;
840 0 : aSource = m_aMediaDescriptor.get( "Stream" );
841 0 : if ( !aSource.hasValue() )
842 0 : aSource = m_aMediaDescriptor.get( "InputStream" );
843 0 : if ( !aSource.hasValue() && !m_sDocFileLocation.isEmpty() )
844 0 : aSource <<= m_sDocFileLocation;
845 : // TODO: shouldn't we also check URL?
846 :
847 : OSL_ENSURE( aSource.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" );
848 :
849 0 : if ( aSource.hasValue() )
850 : {
851 0 : Sequence< Any > aStorageCreationArgs(2);
852 0 : aStorageCreationArgs[0] = aSource;
853 0 : aStorageCreationArgs[1] <<= ElementModes::READWRITE;
854 :
855 0 : Reference< XStorage > xDocumentStorage;
856 : try
857 : {
858 0 : xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
859 : }
860 0 : catch( const Exception& )
861 : {
862 0 : m_bDocumentReadOnly = sal_True;
863 0 : aStorageCreationArgs[1] <<= ElementModes::READ;
864 : try
865 : {
866 0 : xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
867 : }
868 0 : catch( const Exception& )
869 : {
870 : DBG_UNHANDLED_EXCEPTION();
871 : }
872 : }
873 :
874 0 : impl_switchToStorage_throw( xDocumentStorage );
875 0 : }
876 : }
877 0 : return m_xDocumentStorage.getTyped();
878 : }
879 :
880 0 : DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess()
881 : {
882 0 : if ( !m_pStorageAccess )
883 : {
884 0 : m_pStorageAccess = new DocumentStorageAccess( *this );
885 0 : m_pStorageAccess->acquire();
886 : }
887 0 : return m_pStorageAccess;
888 : }
889 :
890 0 : void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess )
891 : {
892 0 : m_xModel = Reference< XModel >();
893 :
894 : // Basic libraries and Dialog libraries are a model facet, though held at this impl class.
895 : // They automatically dispose themself when the model they belong to is being disposed.
896 : // So, to not be tempted to do anything with them, again, we reset them.
897 0 : m_xBasicLibraries.clear();
898 0 : m_xDialogLibraries.clear();
899 :
900 0 : m_bDocumentInitialized = _wasInitialized;
901 0 : }
902 :
903 0 : Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier()
904 : {
905 0 : return getDocumentStorageAccess();
906 : }
907 :
908 0 : bool ODatabaseModelImpl::commitEmbeddedStorage( bool _bPreventRootCommits )
909 : {
910 0 : return getDocumentStorageAccess()->commitEmbeddedStorage( _bPreventRootCommits );
911 : }
912 :
913 0 : bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference< XStorage >& _rxStorage ) SAL_THROW(())
914 : {
915 0 : bool bSuccess = false;
916 : try
917 : {
918 0 : bSuccess = tools::stor::commitStorageIfWriteable( _rxStorage );
919 : }
920 0 : catch( const Exception& )
921 : {
922 : DBG_UNHANDLED_EXCEPTION();
923 : }
924 0 : return bSuccess;
925 : }
926 :
927 0 : void ODatabaseModelImpl::setModified( sal_Bool _bModified )
928 : {
929 0 : if ( isModifyLocked() )
930 0 : return;
931 :
932 : try
933 : {
934 0 : Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY );
935 0 : if ( xModi.is() )
936 0 : xModi->setModified( _bModified );
937 : else
938 0 : m_bModified = _bModified;
939 : }
940 0 : catch( const Exception& )
941 : {
942 : DBG_UNHANDLED_EXCEPTION();
943 : }
944 : }
945 :
946 0 : Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource()
947 : {
948 0 : Reference<XDataSource> xDs = m_xDataSource;
949 0 : if ( !xDs.is() )
950 : {
951 0 : xDs = new ODatabaseSource(this);
952 0 : m_xDataSource = xDs;
953 : }
954 0 : return xDs;
955 : }
956 :
957 0 : Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const
958 : {
959 0 : return m_xModel;
960 : }
961 :
962 0 : Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize )
963 : {
964 0 : Reference< XModel > xModel( m_xModel );
965 : OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" );
966 0 : if ( !xModel.is() )
967 : {
968 0 : bool bHadModelBefore = m_bDocumentInitialized;
969 :
970 0 : xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
971 0 : m_xModel = xModel;
972 :
973 : try
974 : {
975 0 : Reference< XGlobalEventBroadcaster > xModelCollection = GlobalEventBroadcaster::create( m_aContext.getUNOContext() );
976 0 : xModelCollection->insert( makeAny( xModel ) );
977 : }
978 0 : catch( const Exception& )
979 : {
980 : DBG_UNHANDLED_EXCEPTION();
981 : }
982 :
983 0 : if ( bHadModelBefore )
984 : {
985 : // do an attachResources
986 : // In case the document is loaded regularly, this is not necessary, as our loader will do it.
987 : // However, in case that the document is implicitly created by asking the data source for the document,
988 : // then nobody would call the doc's attachResource. So, we do it here, to ensure it's in a proper
989 : // state, fires all events, and so on.
990 : // #i105505#
991 0 : xModel->attachResource( xModel->getURL(), m_aMediaDescriptor.getPropertyValues() );
992 : }
993 :
994 0 : if ( _bInitialize )
995 : {
996 : try
997 : {
998 0 : Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
999 0 : xLoad->initNew();
1000 : }
1001 0 : catch( RuntimeException& ) { throw; }
1002 0 : catch( const Exception& )
1003 : {
1004 : DBG_UNHANDLED_EXCEPTION();
1005 : }
1006 : }
1007 : }
1008 0 : return xModel;
1009 : }
1010 :
1011 0 : oslInterlockedCount SAL_CALL ODatabaseModelImpl::acquire()
1012 : {
1013 0 : return osl_atomic_increment(&m_refCount);
1014 : }
1015 :
1016 0 : oslInterlockedCount SAL_CALL ODatabaseModelImpl::release()
1017 : {
1018 0 : if ( osl_atomic_decrement(&m_refCount) == 0 )
1019 : {
1020 0 : acquire(); // prevent multiple releases
1021 0 : m_pDBContext->removeFromTerminateListener(*this);
1022 0 : dispose();
1023 0 : m_pDBContext->storeTransientProperties(*this);
1024 0 : revokeDataSource();
1025 0 : delete this;
1026 0 : return 0;
1027 : }
1028 0 : return m_refCount;
1029 : }
1030 :
1031 0 : void ODatabaseModelImpl::commitStorages() SAL_THROW(( IOException, RuntimeException ))
1032 : {
1033 0 : getDocumentStorageAccess()->commitStorages();
1034 0 : }
1035 :
1036 0 : Reference< XStorage > ODatabaseModelImpl::getStorage( const ObjectType _eType, const sal_Int32 _nDesiredMode )
1037 : {
1038 0 : return getDocumentStorageAccess()->getDocumentSubStorage( getObjectContainerStorageName( _eType ), _nDesiredMode );
1039 : }
1040 :
1041 0 : const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings()
1042 : {
1043 : static const AsciiPropertyValue aKnownSettings[] =
1044 : {
1045 : // known JDBC settings
1046 : AsciiPropertyValue( "JavaDriverClass", makeAny( ::rtl::OUString() ) ),
1047 : AsciiPropertyValue( "JavaDriverClassPath", makeAny( ::rtl::OUString() ) ),
1048 : AsciiPropertyValue( "IgnoreCurrency", makeAny( (sal_Bool)sal_False ) ),
1049 : // known settings for file-based drivers
1050 : AsciiPropertyValue( "Extension", makeAny( ::rtl::OUString() ) ),
1051 : AsciiPropertyValue( "CharSet", makeAny( ::rtl::OUString() ) ),
1052 : AsciiPropertyValue( "HeaderLine", makeAny( (sal_Bool)sal_True ) ),
1053 : AsciiPropertyValue( "FieldDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ) ),
1054 : AsciiPropertyValue( "StringDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ) ) ),
1055 : AsciiPropertyValue( "DecimalDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ),
1056 : AsciiPropertyValue( "ThousandDelimiter", makeAny( ::rtl::OUString() ) ),
1057 : AsciiPropertyValue( "ShowDeleted", makeAny( (sal_Bool)sal_False ) ),
1058 : // known ODBC settings
1059 : AsciiPropertyValue( "SystemDriverSettings", makeAny( ::rtl::OUString() ) ),
1060 : AsciiPropertyValue( "UseCatalog", makeAny( (sal_Bool)sal_False ) ),
1061 : AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence< Any >()) ),
1062 : // settings related to auto increment handling
1063 : AsciiPropertyValue( "AutoIncrementCreation", makeAny( ::rtl::OUString() ) ),
1064 : AsciiPropertyValue( "AutoRetrievingStatement", makeAny( ::rtl::OUString() ) ),
1065 : AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( (sal_Bool)sal_False ) ),
1066 : // known LDAP driver settings
1067 : AsciiPropertyValue( "HostName", makeAny( ::rtl::OUString() ) ),
1068 : AsciiPropertyValue( "PortNumber", makeAny( (sal_Int32)389 ) ),
1069 : AsciiPropertyValue( "BaseDN", makeAny( ::rtl::OUString() ) ),
1070 : AsciiPropertyValue( "MaxRowCount", makeAny( (sal_Int32)100 ) ),
1071 : // known MySQLNative driver settings
1072 : AsciiPropertyValue( "LocalSocket", makeAny( ::rtl::OUString() ) ),
1073 : AsciiPropertyValue( "NamedPipe", makeAny( ::rtl::OUString() ) ),
1074 : // misc known driver settings
1075 : AsciiPropertyValue( "ParameterNameSubstitution", makeAny( (sal_Bool)sal_False ) ),
1076 : AsciiPropertyValue( "AddIndexAppendix", makeAny( (sal_Bool)sal_True ) ),
1077 : AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( (sal_Bool)sal_True ) ),
1078 0 : AsciiPropertyValue( "ImplicitCatalogRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ),
1079 0 : AsciiPropertyValue( "ImplicitSchemaRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ),
1080 0 : AsciiPropertyValue( "PrimaryKeySupport", ::cppu::UnoType< sal_Bool >::get() ),
1081 : AsciiPropertyValue( "ShowColumnDescription", makeAny( (sal_Bool)sal_False ) ),
1082 : // known SDB level settings
1083 : AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool)sal_False ) ),
1084 : AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool)sal_False ) ),
1085 : AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( (sal_Bool)sal_True ) ),
1086 : AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( (sal_Bool)sal_True ) ),
1087 : AsciiPropertyValue( "EnableSQL92Check", makeAny( (sal_Bool)sal_False ) ),
1088 : AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER ) ),
1089 : AsciiPropertyValue( "TableTypeFilterMode", makeAny( (sal_Int32)3 ) ),
1090 : AsciiPropertyValue( "RespectDriverResultSetType", makeAny( (sal_Bool)sal_False ) ),
1091 : AsciiPropertyValue( "UseSchemaInSelect", makeAny( (sal_Bool)sal_True ) ),
1092 : AsciiPropertyValue( "UseCatalogInSelect", makeAny( (sal_Bool)sal_True ) ),
1093 : AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( (sal_Bool)sal_True ) ),
1094 : AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( (sal_Bool)sal_False ) ),
1095 : AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( (sal_Bool)sal_True ) ),
1096 : AsciiPropertyValue( "EscapeDateTime", makeAny( (sal_Bool)sal_True ) ),
1097 :
1098 : // known services to handle database tasks
1099 : AsciiPropertyValue( "TableAlterationServiceName", makeAny( ::rtl::OUString() ) ),
1100 : AsciiPropertyValue( "TableRenameServiceName", makeAny( ::rtl::OUString() ) ),
1101 : AsciiPropertyValue( "ViewAlterationServiceName", makeAny( ::rtl::OUString() ) ),
1102 : AsciiPropertyValue( "ViewAccessServiceName", makeAny( ::rtl::OUString() ) ),
1103 : AsciiPropertyValue( "CommandDefinitions", makeAny( ::rtl::OUString() ) ),
1104 : AsciiPropertyValue( "Forms", makeAny( ::rtl::OUString() ) ),
1105 : AsciiPropertyValue( "Reports", makeAny( ::rtl::OUString() ) ),
1106 : AsciiPropertyValue( "KeyAlterationServiceName", makeAny( ::rtl::OUString() ) ),
1107 : AsciiPropertyValue( "IndexAlterationServiceName", makeAny( ::rtl::OUString() ) ),
1108 :
1109 : AsciiPropertyValue()
1110 0 : };
1111 0 : return aKnownSettings;
1112 : }
1113 :
1114 0 : TContentPtr& ODatabaseModelImpl::getObjectContainer( ObjectType _eType )
1115 : {
1116 : OSL_PRECOND( _eType >= E_FORM && _eType <= E_TABLE, "ODatabaseModelImpl::getObjectContainer: illegal index!" );
1117 0 : TContentPtr& rContentPtr = m_aContainer[ _eType ];
1118 :
1119 0 : if ( !rContentPtr.get() )
1120 : {
1121 0 : rContentPtr = TContentPtr( new ODefinitionContainer_Impl );
1122 0 : rContentPtr->m_pDataSource = this;
1123 0 : rContentPtr->m_aProps.aTitle = lcl_getContainerStorageName_throw( _eType );
1124 : }
1125 0 : return rContentPtr;
1126 : }
1127 :
1128 0 : void ODatabaseModelImpl::revokeDataSource() const
1129 : {
1130 0 : if ( m_pDBContext && !m_sDocumentURL.isEmpty() )
1131 0 : m_pDBContext->revokeDatabaseDocument( *this );
1132 0 : }
1133 :
1134 0 : bool ODatabaseModelImpl::adjustMacroMode_AutoReject()
1135 : {
1136 0 : return m_aMacroMode.adjustMacroMode( NULL );
1137 : }
1138 :
1139 0 : bool ODatabaseModelImpl::checkMacrosOnLoading()
1140 : {
1141 0 : Reference< XInteractionHandler > xInteraction;
1142 0 : xInteraction = m_aMediaDescriptor.getOrDefault( "InteractionHandler", xInteraction );
1143 0 : return m_aMacroMode.checkMacrosOnLoading( xInteraction );
1144 : }
1145 :
1146 0 : void ODatabaseModelImpl::resetMacroExecutionMode()
1147 : {
1148 0 : m_aMacroMode = ::sfx2::DocumentMacroMode( *this );
1149 0 : }
1150 :
1151 0 : Reference< XStorageBasedLibraryContainer > ODatabaseModelImpl::getLibraryContainer( bool _bScript )
1152 : {
1153 0 : Reference< XStorageBasedLibraryContainer >& rxContainer( _bScript ? m_xBasicLibraries : m_xDialogLibraries );
1154 0 : if ( rxContainer.is() )
1155 0 : return rxContainer;
1156 :
1157 0 : Reference< XStorageBasedDocument > xDocument( getModel_noCreate(), UNO_QUERY_THROW );
1158 : // this is only to be called if there already exists a document model - in fact, it is
1159 : // to be called by the document model only
1160 :
1161 : try
1162 : {
1163 : Reference< XStorageBasedLibraryContainer > (*Factory)( const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)
1164 0 : = _bScript ? &DocumentScriptLibraryContainer::create : &DocumentDialogLibraryContainer::create;
1165 :
1166 : rxContainer.set(
1167 : (*Factory)( m_aContext.getUNOContext(), xDocument ),
1168 : UNO_QUERY_THROW
1169 0 : );
1170 : }
1171 0 : catch( const RuntimeException& )
1172 : {
1173 0 : throw;
1174 : }
1175 0 : catch( const Exception& )
1176 : {
1177 : throw WrappedTargetRuntimeException(
1178 : ::rtl::OUString(),
1179 : xDocument,
1180 : ::cppu::getCaughtException()
1181 0 : );
1182 : }
1183 0 : return rxContainer;
1184 : }
1185 :
1186 0 : void ODatabaseModelImpl::storeLibraryContainersTo( const Reference< XStorage >& _rxToRootStorage )
1187 : {
1188 0 : if ( m_xBasicLibraries.is() )
1189 0 : m_xBasicLibraries->storeLibrariesToStorage( _rxToRootStorage );
1190 :
1191 0 : if ( m_xDialogLibraries.is() )
1192 0 : m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage );
1193 0 : }
1194 :
1195 0 : Reference< XStorage > ODatabaseModelImpl::switchToStorage( const Reference< XStorage >& _rxNewRootStorage )
1196 : {
1197 0 : if ( !_rxNewRootStorage.is() )
1198 0 : throw IllegalArgumentException();
1199 :
1200 0 : return impl_switchToStorage_throw( _rxNewRootStorage );
1201 : }
1202 :
1203 : namespace
1204 : {
1205 0 : void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument,
1206 : const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener,
1207 : ::osl::SolarMutex& _rMutex, bool _bListen )
1208 : {
1209 0 : Reference< XModifiable > xModify( _rxStorage, UNO_QUERY );
1210 : OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" );
1211 :
1212 0 : if ( xModify.is() && !_bListen && _inout_rListener.is() )
1213 : {
1214 0 : xModify->removeModifyListener( _inout_rListener.get() );
1215 : }
1216 :
1217 0 : if ( _inout_rListener.is() )
1218 : {
1219 0 : _inout_rListener->dispose();
1220 0 : _inout_rListener = NULL;
1221 : }
1222 :
1223 0 : if ( xModify.is() && _bListen )
1224 : {
1225 0 : _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex );
1226 0 : xModify->addModifyListener( _inout_rListener.get() );
1227 0 : }
1228 0 : }
1229 : }
1230 :
1231 : namespace
1232 : {
1233 0 : static void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer,
1234 : const Reference< XStorage >& _rxNewRootStorage )
1235 : {
1236 0 : if ( _rxContainer.is() )
1237 : {
1238 0 : if ( _rxNewRootStorage.is() )
1239 0 : _rxContainer->setRootStorage( _rxNewRootStorage );
1240 : // else
1241 : // TODO: what to do here? dispose the container?
1242 : }
1243 0 : }
1244 : }
1245 :
1246 0 : Reference< XStorage > ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage )
1247 : {
1248 : // stop listening for modifications at the old storage
1249 0 : lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, false );
1250 :
1251 : // set new storage
1252 0 : m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership );
1253 :
1254 : // start listening for modifications
1255 0 : lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, true );
1256 :
1257 : // forward new storage to Basic and Dialog library containers
1258 0 : lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() );
1259 0 : lcl_rebaseScriptStorage_throw( m_xDialogLibraries, m_xDocumentStorage.getTyped() );
1260 :
1261 0 : m_bReadOnly = !tools::stor::storageIsWritable_nothrow( m_xDocumentStorage.getTyped() );
1262 : // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property
1263 :
1264 0 : return m_xDocumentStorage.getTyped();
1265 : }
1266 :
1267 0 : void ODatabaseModelImpl::impl_switchToLogicalURL( const ::rtl::OUString& i_rDocumentURL )
1268 : {
1269 0 : if ( i_rDocumentURL == m_sDocumentURL )
1270 0 : return;
1271 :
1272 0 : const ::rtl::OUString sOldURL( m_sDocumentURL );
1273 : // update our name, if necessary
1274 0 : if ( ( m_sName == m_sDocumentURL ) // our name is our old URL
1275 0 : || ( m_sName.isEmpty() ) // we do not have a name, yet (i.e. are not registered at the database context)
1276 : )
1277 : {
1278 0 : INetURLObject aURL( i_rDocumentURL );
1279 0 : if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
1280 : {
1281 0 : m_sName = i_rDocumentURL;
1282 : // TODO: our data source must broadcast the change of the Name property
1283 0 : }
1284 : }
1285 :
1286 : // remember URL
1287 0 : m_sDocumentURL = i_rDocumentURL;
1288 :
1289 : // update our location, if necessary
1290 0 : if ( m_sDocFileLocation.isEmpty() )
1291 0 : m_sDocFileLocation = m_sDocumentURL;
1292 :
1293 : // register at the database context, or change registration
1294 0 : if ( m_pDBContext )
1295 : {
1296 0 : if ( !sOldURL.isEmpty() )
1297 0 : m_pDBContext->databaseDocumentURLChange( sOldURL, m_sDocumentURL );
1298 : else
1299 0 : m_pDBContext->registerDatabaseDocument( *this );
1300 0 : }
1301 : }
1302 :
1303 0 : ::rtl::OUString ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType )
1304 : {
1305 0 : return lcl_getContainerStorageName_throw( _eType );
1306 : }
1307 :
1308 0 : sal_Int16 ODatabaseModelImpl::getCurrentMacroExecMode() const
1309 : {
1310 0 : sal_Int16 nCurrentMode = MacroExecMode::NEVER_EXECUTE;
1311 : try
1312 : {
1313 0 : nCurrentMode = m_aMediaDescriptor.getOrDefault( "MacroExecutionMode", nCurrentMode );
1314 : }
1315 0 : catch( const Exception& )
1316 : {
1317 : DBG_UNHANDLED_EXCEPTION();
1318 : }
1319 0 : return nCurrentMode;
1320 : }
1321 :
1322 0 : sal_Bool ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1323 : {
1324 0 : m_aMediaDescriptor.put( "MacroExecutionMode", nMacroMode );
1325 0 : return sal_True;
1326 : }
1327 :
1328 0 : ::rtl::OUString ODatabaseModelImpl::getDocumentLocation() const
1329 : {
1330 0 : return getURL();
1331 : // formerly, we returned getDocFileLocation here, which is the location of the file from which we
1332 : // recovered the "real" document.
1333 : // However, during CWS autorecovery evolving, we clarified (with MAV/MT) the role of XModel::getURL and
1334 : // XStorable::getLocation. In this course, we agreed that for a macro security check, the *document URL*
1335 : // (not the recovery file URL) is to be used: The recovery file lies in the backup folder, and by definition,
1336 : // this folder is considered to be secure. So, the document URL needs to be used to decide about the security.
1337 : }
1338 :
1339 0 : Reference< XStorage > ODatabaseModelImpl::getZipStorageToSign()
1340 : {
1341 : // we do not support signing the scripting storages, so we're allowed to
1342 : // return <NULL/> here.
1343 0 : return Reference< XStorage >();
1344 : }
1345 :
1346 0 : ODatabaseModelImpl::EmbeddedMacros ODatabaseModelImpl::determineEmbeddedMacros()
1347 : {
1348 0 : if ( !m_aEmbeddedMacros )
1349 : {
1350 0 : if ( ::sfx2::DocumentMacroMode::storageHasMacros( const_cast< ODatabaseModelImpl* >( this )->getOrCreateRootStorage() ) )
1351 : {
1352 0 : m_aEmbeddedMacros.reset( eDocumentWideMacros );
1353 : }
1354 0 : else if ( lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_FORM )
1355 0 : || lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_REPORT )
1356 : )
1357 : {
1358 0 : m_aEmbeddedMacros.reset( eSubDocumentMacros );
1359 : }
1360 : else
1361 : {
1362 0 : m_aEmbeddedMacros.reset( eNoMacros );
1363 : }
1364 : }
1365 0 : return *m_aEmbeddedMacros;
1366 : }
1367 :
1368 0 : sal_Bool ODatabaseModelImpl::documentStorageHasMacros() const
1369 : {
1370 0 : const_cast< ODatabaseModelImpl* >( this )->determineEmbeddedMacros();
1371 0 : return ( *m_aEmbeddedMacros != eNoMacros );
1372 : }
1373 :
1374 0 : Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const
1375 : {
1376 0 : return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY );
1377 : }
1378 :
1379 0 : sal_Int16 ODatabaseModelImpl::getScriptingSignatureState()
1380 : {
1381 : // no support for signatures at the moment
1382 0 : return SIGNATURESTATE_NOSIGNATURES;
1383 : }
1384 :
1385 0 : sal_Bool ODatabaseModelImpl::hasTrustedScriptingSignature( sal_Bool /*bAllowUIToAddAuthor*/ )
1386 : {
1387 : // no support for signatures at the moment
1388 0 : return sal_False;
1389 : }
1390 :
1391 0 : void ODatabaseModelImpl::showBrokenSignatureWarning( const Reference< XInteractionHandler >& /*_rxInteraction*/ ) const
1392 : {
1393 : OSL_FAIL( "ODatabaseModelImpl::showBrokenSignatureWarning: signatures can't be broken - we do not support them!" );
1394 0 : }
1395 :
1396 0 : void ODatabaseModelImpl::storageIsModified()
1397 : {
1398 0 : setModified( sal_True );
1399 0 : }
1400 :
1401 0 : ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model )
1402 : :m_pImpl( _model )
1403 0 : ,m_aMutex( _model->getSharedMutex() )
1404 : {
1405 0 : }
1406 :
1407 0 : ModelDependentComponent::~ModelDependentComponent()
1408 : {
1409 0 : }
1410 :
1411 : } // namespace dbaccess
1412 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|