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