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