Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include "subcomponentrecovery.hxx"
22 : :
23 : : #include "sdbcoretools.hxx"
24 : : #include "storagexmlstream.hxx"
25 : : #include "subcomponentloader.hxx"
26 : : #include "settingsimport.hxx"
27 : :
28 : : #include <com/sun/star/embed/ElementModes.hpp>
29 : : #include <com/sun/star/frame/XModuleManager.hpp>
30 : : #include <com/sun/star/document/XStorageBasedDocument.hpp>
31 : : #include <com/sun/star/ucb/XCommandProcessor.hpp>
32 : : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
33 : : #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
34 : : #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
35 : : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
36 : :
37 : : #include <comphelper/namedvaluecollection.hxx>
38 : : #include <connectivity/dbtools.hxx>
39 : : #include <tools/diagnose_ex.h>
40 : : #include <xmloff/XMLSettingsExportContext.hxx>
41 : : #include <xmloff/SettingsExportHelper.hxx>
42 : :
43 : : //........................................................................
44 : : namespace dbaccess
45 : : {
46 : : //........................................................................
47 : :
48 : : /** === begin UNO using === **/
49 : : using ::com::sun::star::uno::Reference;
50 : : using ::com::sun::star::uno::XInterface;
51 : : using ::com::sun::star::uno::UNO_QUERY;
52 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
53 : : using ::com::sun::star::uno::UNO_SET_THROW;
54 : : using ::com::sun::star::uno::Exception;
55 : : using ::com::sun::star::uno::RuntimeException;
56 : : using ::com::sun::star::uno::Any;
57 : : using ::com::sun::star::uno::makeAny;
58 : : using ::com::sun::star::uno::Sequence;
59 : : using ::com::sun::star::uno::Type;
60 : : using ::com::sun::star::lang::XMultiServiceFactory;
61 : : using ::com::sun::star::embed::XStorage;
62 : : using ::com::sun::star::sdb::application::XDatabaseDocumentUI;
63 : : using ::com::sun::star::beans::Pair;
64 : : using ::com::sun::star::frame::XModuleManager;
65 : : using ::com::sun::star::lang::XComponent;
66 : : using ::com::sun::star::frame::XModel;
67 : : using ::com::sun::star::frame::XController;
68 : : using ::com::sun::star::beans::XPropertySet;
69 : : using ::com::sun::star::beans::PropertyValue;
70 : : using ::com::sun::star::document::XStorageBasedDocument;
71 : : using ::com::sun::star::ucb::XCommandProcessor;
72 : : using ::com::sun::star::container::XHierarchicalNameAccess;
73 : : using ::com::sun::star::sdb::XFormDocumentsSupplier;
74 : : using ::com::sun::star::sdb::XReportDocumentsSupplier;
75 : : using ::com::sun::star::xml::sax::SAXException;
76 : : using ::com::sun::star::xml::sax::XLocator;
77 : : using ::com::sun::star::xml::sax::XDocumentHandler;
78 : : using ::com::sun::star::xml::sax::XAttributeList;
79 : : /** === end UNO using === **/
80 : :
81 : : namespace ElementModes = ::com::sun::star::embed::ElementModes;
82 : :
83 : :
84 : : //====================================================================
85 : : //= helper
86 : : //====================================================================
87 : : namespace
88 : : {
89 : : // .........................................................................
90 : 0 : static const ::rtl::OUString& lcl_getComponentStorageBaseName( const SubComponentType i_eType )
91 : : {
92 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sFormBaseName( RTL_CONSTASCII_USTRINGPARAM( "form" ) );
[ # # ][ # # ]
93 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sReportBaseName( RTL_CONSTASCII_USTRINGPARAM( "report" ) );
[ # # ][ # # ]
94 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sTableBaseName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
[ # # ][ # # ]
95 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sQueryBaseName( RTL_CONSTASCII_USTRINGPARAM( "query" ) );
[ # # ][ # # ]
96 : :
97 [ # # # # : 0 : switch ( i_eType )
# ]
98 : : {
99 : : case FORM:
100 : 0 : return s_sFormBaseName;
101 : : case REPORT:
102 : 0 : return s_sReportBaseName;
103 : : case TABLE:
104 : 0 : return s_sTableBaseName;
105 : : case QUERY:
106 : 0 : return s_sQueryBaseName;
107 : : default:
108 : 0 : break;
109 : : }
110 : :
111 : : OSL_FAIL( "lcl_getComponentStorageBaseName: unimplemented case!" );
112 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sFallback;
113 : 0 : return s_sFallback;
114 : : }
115 : :
116 : : // .........................................................................
117 : 0 : static SubComponentType lcl_databaseObjectToSubComponentType( const sal_Int32 i_nObjectType )
118 : : {
119 [ # # # # : 0 : switch ( i_nObjectType )
# ]
120 : : {
121 : 0 : case DatabaseObject::TABLE: return TABLE;
122 : 0 : case DatabaseObject::QUERY: return QUERY;
123 : 0 : case DatabaseObject::FORM: return FORM;
124 : 0 : case DatabaseObject::REPORT:return REPORT;
125 : : default:
126 : 0 : break;
127 : : }
128 : 0 : return UNKNOWN;
129 : : }
130 : :
131 : : // .........................................................................
132 : 0 : static bool lcl_determineReadOnly( const Reference< XComponent >& i_rComponent )
133 : : {
134 [ # # ]: 0 : Reference< XModel > xDocument( i_rComponent, UNO_QUERY );
135 [ # # ]: 0 : if ( !xDocument.is() )
136 : : {
137 [ # # ]: 0 : Reference< XController > xController( i_rComponent, UNO_QUERY_THROW );
138 [ # # ][ # # ]: 0 : xDocument = xController->getModel();
[ # # ]
139 : : }
140 : :
141 [ # # ]: 0 : if ( !xDocument.is() )
142 : 0 : return false;
143 : :
144 [ # # ][ # # ]: 0 : ::comphelper::NamedValueCollection aDocArgs( xDocument->getArgs() );
[ # # ][ # # ]
145 [ # # ][ # # ]: 0 : return aDocArgs.getOrDefault( "ReadOnly", false );
146 : : }
147 : :
148 : : // .........................................................................
149 : 0 : static Reference< XCommandProcessor > lcl_getSubComponentDef_nothrow( const Reference< XDatabaseDocumentUI >& i_rAppUI,
150 : : const SubComponentType i_eType, const ::rtl::OUString& i_rName )
151 : : {
152 [ # # ]: 0 : Reference< XController > xController( i_rAppUI, UNO_QUERY_THROW );
153 [ # # ][ # # ]: 0 : ENSURE_OR_RETURN( ( i_eType == FORM ) || ( i_eType == REPORT ), "lcl_getSubComponentDef_nothrow: illegal controller", NULL );
[ # # ]
154 : :
155 : 0 : Reference< XCommandProcessor > xCommandProcessor;
156 : : try
157 : : {
158 : 0 : Reference< XHierarchicalNameAccess > xDefinitionContainer;
159 [ # # ]: 0 : if ( i_eType == FORM )
160 : : {
161 [ # # ][ # # ]: 0 : Reference< XFormDocumentsSupplier > xSuppForms( xController->getModel(), UNO_QUERY_THROW );
[ # # ]
162 [ # # ][ # # ]: 0 : xDefinitionContainer.set( xSuppForms->getFormDocuments(), UNO_QUERY_THROW );
[ # # ]
163 : : }
164 : : else
165 : : {
166 [ # # ][ # # ]: 0 : Reference< XReportDocumentsSupplier > xSuppReports( xController->getModel(), UNO_QUERY_THROW );
[ # # ]
167 [ # # ][ # # ]: 0 : xDefinitionContainer.set( xSuppReports->getReportDocuments(), UNO_QUERY_THROW );
[ # # ]
168 : : }
169 [ # # ][ # # ]: 0 : xCommandProcessor.set( xDefinitionContainer->getByHierarchicalName( i_rName ), UNO_QUERY_THROW );
[ # # ][ # # ]
170 : : }
171 [ # # ]: 0 : catch( const Exception& )
172 : : {
173 : : DBG_UNHANDLED_EXCEPTION();
174 : : }
175 : 0 : return xCommandProcessor;
176 : : }
177 : :
178 : : // .........................................................................
179 : 0 : static const ::rtl::OUString& lcl_getSettingsStreamName()
180 : : {
181 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sStatementStreamName( RTL_CONSTASCII_USTRINGPARAM( "settings.xml" ) );
[ # # ][ # # ]
182 : 0 : return s_sStatementStreamName;
183 : : }
184 : :
185 : : // .........................................................................
186 : 0 : static const ::rtl::OUString& lcl_getCurrentQueryDesignName()
187 : : {
188 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sQuerySettingsName( RTL_CONSTASCII_USTRINGPARAM( "ooo:current-query-design" ) );
[ # # ][ # # ]
189 : 0 : return s_sQuerySettingsName;
190 : : }
191 : : }
192 : :
193 : : //====================================================================
194 : : //= SettingsExportContext
195 : : //====================================================================
196 : : class DBACCESS_DLLPRIVATE SettingsExportContext : public ::xmloff::XMLSettingsExportContext
197 : : {
198 : : public:
199 : 0 : SettingsExportContext( const ::comphelper::ComponentContext& i_rContext, const StorageXMLOutputStream& i_rDelegator )
200 : : :m_rContext( i_rContext )
201 : : ,m_rDelegator( i_rDelegator )
202 [ # # ][ # # ]: 0 : ,m_aNamespace( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_NP_CONFIG ) )
203 : : {
204 : 0 : }
205 : :
206 : 0 : virtual ~SettingsExportContext()
207 : 0 : {
208 [ # # ]: 0 : }
209 : :
210 : : public:
211 : : virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue );
212 : : virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue );
213 : : virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace );
214 : : virtual void EndElement ( const sal_Bool i_bIgnoreWhitespace );
215 : : virtual void Characters( const ::rtl::OUString& i_rCharacters );
216 : :
217 : : virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
218 : : GetServiceFactory() const;
219 : :
220 : : private:
221 : 0 : ::rtl::OUString impl_prefix( const ::xmloff::token::XMLTokenEnum i_eToken )
222 : : {
223 [ # # ]: 0 : ::rtl::OUStringBuffer aQualifiedName( m_aNamespace );
224 [ # # ]: 0 : aQualifiedName.append( sal_Unicode( ':' ) );
225 [ # # ][ # # ]: 0 : aQualifiedName.append( ::xmloff::token::GetXMLToken( i_eToken ) );
226 [ # # ]: 0 : return aQualifiedName.makeStringAndClear();
227 : : }
228 : :
229 : : private:
230 : : const ::comphelper::ComponentContext& m_rContext;
231 : : const StorageXMLOutputStream& m_rDelegator;
232 : : const ::rtl::OUStringBuffer m_aNamespace;
233 : : };
234 : :
235 : : //--------------------------------------------------------------------
236 : 0 : void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue )
237 : : {
238 [ # # ]: 0 : m_rDelegator.addAttribute( impl_prefix( i_eName ), i_rValue );
239 : 0 : }
240 : :
241 : : //--------------------------------------------------------------------
242 : 0 : void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue )
243 : : {
244 [ # # ]: 0 : m_rDelegator.addAttribute( impl_prefix( i_eName ), ::xmloff::token::GetXMLToken( i_eValue ) );
245 : 0 : }
246 : :
247 : : //--------------------------------------------------------------------
248 : 0 : void SettingsExportContext::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace )
249 : : {
250 [ # # ]: 0 : if ( i_bIgnoreWhitespace )
251 [ # # ]: 0 : m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
252 : :
253 [ # # ]: 0 : m_rDelegator.startElement( impl_prefix( i_eName ) );
254 : 0 : }
255 : :
256 : : //--------------------------------------------------------------------
257 : 0 : void SettingsExportContext::EndElement( const sal_Bool i_bIgnoreWhitespace )
258 : : {
259 [ # # ]: 0 : if ( i_bIgnoreWhitespace )
260 [ # # ]: 0 : m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
261 : 0 : m_rDelegator.endElement();
262 : 0 : }
263 : :
264 : : //--------------------------------------------------------------------
265 : 0 : void SettingsExportContext::Characters( const ::rtl::OUString& i_rCharacters )
266 : : {
267 : 0 : m_rDelegator.characters( i_rCharacters );
268 : 0 : }
269 : :
270 : : //--------------------------------------------------------------------
271 : 0 : Reference< XMultiServiceFactory > SettingsExportContext::GetServiceFactory() const
272 : : {
273 : 0 : return m_rContext.getLegacyServiceFactory();
274 : : }
275 : :
276 : : //==================================================================================================================
277 : : //= SettingsDocumentHandler
278 : : //==================================================================================================================
279 : : typedef ::cppu::WeakImplHelper1 < XDocumentHandler
280 : : > SettingsDocumentHandler_Base;
281 : : class DBACCESS_DLLPRIVATE SettingsDocumentHandler : public SettingsDocumentHandler_Base
282 : : {
283 : : public:
284 : 0 : SettingsDocumentHandler()
285 [ # # ][ # # ]: 0 : {
[ # # ]
286 : 0 : }
287 : :
288 : : protected:
289 : 0 : virtual ~SettingsDocumentHandler()
290 [ # # ]: 0 : {
291 [ # # ]: 0 : }
292 : :
293 : : public:
294 : : // XDocumentHandler
295 : : virtual void SAL_CALL startDocument( ) throw (SAXException, RuntimeException);
296 : : virtual void SAL_CALL endDocument( ) throw (SAXException, RuntimeException);
297 : : virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const Reference< XAttributeList >& xAttribs ) throw (SAXException, RuntimeException);
298 : : virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (SAXException, RuntimeException);
299 : : virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (SAXException, RuntimeException);
300 : : virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (SAXException, RuntimeException);
301 : : virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (SAXException, RuntimeException);
302 : : virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException);
303 : :
304 : 0 : const ::comphelper::NamedValueCollection& getSettings() const { return m_aSettings; }
305 : :
306 : : private:
307 : : ::std::stack< ::rtl::Reference< SettingsImport > > m_aStates;
308 : : ::comphelper::NamedValueCollection m_aSettings;
309 : : };
310 : :
311 : : //--------------------------------------------------------------------
312 : 0 : void SAL_CALL SettingsDocumentHandler::startDocument( ) throw (SAXException, RuntimeException)
313 : : {
314 : 0 : }
315 : :
316 : : //--------------------------------------------------------------------
317 : 0 : void SAL_CALL SettingsDocumentHandler::endDocument( ) throw (SAXException, RuntimeException)
318 : : {
319 : 0 : }
320 : :
321 : : //--------------------------------------------------------------------
322 : 0 : void SAL_CALL SettingsDocumentHandler::startElement( const ::rtl::OUString& i_Name, const Reference< XAttributeList >& i_Attribs ) throw (SAXException, RuntimeException)
323 : : {
324 : 0 : ::rtl::Reference< SettingsImport > pNewState;
325 : :
326 [ # # ]: 0 : if ( m_aStates.empty() )
327 : : {
328 [ # # ]: 0 : if ( i_Name == "office:settings" )
329 : : {
330 [ # # ][ # # ]: 0 : pNewState = new OfficeSettingsImport( m_aSettings );
[ # # ]
331 : : }
332 : : else
333 : : {
334 : : OSL_FAIL( "SettingsDocumentHandler::startElement: invalid settings file!" );
335 : : // Yes, that's not correct. Somebody could, in theory, give us a document which starts with "foo:settings",
336 : : // where "foo" is mapped to the proper namespace URL.
337 : : // However, there's no need to bother with this. The "recovery" sub storage we're recovering from is
338 : : // not part of ODF, so we can impose any format restrictions on it ...
339 : : }
340 : : }
341 : : else
342 : : {
343 [ # # ][ # # ]: 0 : ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() );
344 [ # # ][ # # ]: 0 : pNewState = pCurrentState->nextState( i_Name );
[ # # ][ # # ]
345 : : }
346 : :
347 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( pNewState.is(), "no new state - aborting import" );
[ # # ][ # # ]
348 [ # # ]: 0 : pNewState->startElement( i_Attribs );
349 : :
350 [ # # ][ # # ]: 0 : m_aStates.push( pNewState );
351 : 0 : }
352 : :
353 : : //--------------------------------------------------------------------
354 : 0 : void SAL_CALL SettingsDocumentHandler::endElement( const ::rtl::OUString& i_Name ) throw (SAXException, RuntimeException)
355 : : {
356 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( !m_aStates.empty(), "no active element" );
[ # # ][ # # ]
357 : : (void)i_Name;
358 : :
359 [ # # ][ # # ]: 0 : ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() );
360 [ # # ]: 0 : pCurrentState->endElement();
361 [ # # ][ # # ]: 0 : m_aStates.pop();
362 : 0 : }
363 : :
364 : : //--------------------------------------------------------------------
365 : 0 : void SAL_CALL SettingsDocumentHandler::characters( const ::rtl::OUString& i_Chars ) throw (SAXException, RuntimeException)
366 : : {
367 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( !m_aStates.empty(), "no active element" );
[ # # ][ # # ]
368 : :
369 [ # # ][ # # ]: 0 : ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() );
370 [ # # ][ # # ]: 0 : pCurrentState->characters( i_Chars );
371 : 0 : }
372 : :
373 : : //--------------------------------------------------------------------
374 : 0 : void SAL_CALL SettingsDocumentHandler::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (SAXException, RuntimeException)
375 : : {
376 : : // ignore them - that's why they're called "ignorable"
377 : : (void)aWhitespaces;
378 : 0 : }
379 : :
380 : : //--------------------------------------------------------------------
381 : 0 : void SAL_CALL SettingsDocumentHandler::processingInstruction( const ::rtl::OUString& i_Target, const ::rtl::OUString& i_Data ) throw (SAXException, RuntimeException)
382 : : {
383 : : OSL_FAIL( "SettingsDocumentHandler::processingInstruction: unexpected ..." );
384 : : (void)i_Target;
385 : : (void)i_Data;
386 : 0 : }
387 : :
388 : : //--------------------------------------------------------------------
389 : 0 : void SAL_CALL SettingsDocumentHandler::setDocumentLocator( const Reference< XLocator >& i_Locator ) throw (SAXException, RuntimeException)
390 : : {
391 : : (void)i_Locator;
392 : 0 : }
393 : :
394 : : //====================================================================
395 : : //= SubComponentRecovery
396 : : //====================================================================
397 : : //--------------------------------------------------------------------
398 : 0 : const ::rtl::OUString SubComponentRecovery::getComponentsStorageName( const SubComponentType i_eType )
399 : : {
400 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sFormsStorageName( RTL_CONSTASCII_USTRINGPARAM( "forms" ) );
[ # # ][ # # ]
401 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sReportsStorageName( RTL_CONSTASCII_USTRINGPARAM( "reports" ) );
[ # # ][ # # ]
402 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sTablesStorageName( RTL_CONSTASCII_USTRINGPARAM( "tables" ) );
[ # # ][ # # ]
403 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sQueriesStorageName( RTL_CONSTASCII_USTRINGPARAM( "queries" ) );
[ # # ][ # # ]
404 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sRelationsStorageName( RTL_CONSTASCII_USTRINGPARAM( "relations" ) );
[ # # ][ # # ]
405 : :
406 [ # # # # : 0 : switch ( i_eType )
# # ]
407 : : {
408 : : case FORM:
409 : 0 : return s_sFormsStorageName;
410 : : case REPORT:
411 : 0 : return s_sReportsStorageName;
412 : : case TABLE:
413 : 0 : return s_sTablesStorageName;
414 : : case QUERY:
415 : 0 : return s_sQueriesStorageName;
416 : : case RELATION_DESIGN:
417 : 0 : return s_sRelationsStorageName;
418 : : default:
419 : 0 : break;
420 : : }
421 : :
422 : : OSL_FAIL( "SubComponentRecovery::getComponentsStorageName: unimplemented case!" );
423 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sFallback;
424 : 0 : return s_sFallback;
425 : : }
426 : :
427 : : //--------------------------------------------------------------------
428 : 0 : void SubComponentRecovery::saveToRecoveryStorage( const Reference< XStorage >& i_rRecoveryStorage,
429 : : MapCompTypeToCompDescs& io_mapCompDescs )
430 : : {
431 [ # # ]: 0 : if ( m_eType == UNKNOWN )
432 : : // quite fatal, but has already been reported (as assertion) before
433 : 0 : return;
434 : :
435 : : // open the sub storage for the given kind of components
436 [ # # ]: 0 : const ::rtl::OUString& rStorageName( getComponentsStorageName( m_eType ) );
437 [ # # ]: 0 : const Reference< XStorage > xComponentsStorage( i_rRecoveryStorage->openStorageElement(
438 [ # # ][ # # ]: 0 : rStorageName, ElementModes::READWRITE ), UNO_QUERY_THROW );
439 : :
440 : : // find a free sub storage name, and create Yet Another Sub Storage
441 [ # # ]: 0 : const ::rtl::OUString& rBaseName( lcl_getComponentStorageBaseName( m_eType ) );
442 [ # # ][ # # ]: 0 : const ::rtl::OUString sStorName = ::dbtools::createUniqueName( xComponentsStorage.get(), rBaseName, true );
[ # # ]
443 [ # # ]: 0 : const Reference< XStorage > xObjectStor( xComponentsStorage->openStorageElement(
444 [ # # ][ # # ]: 0 : sStorName, ElementModes::READWRITE ), UNO_QUERY_THROW );
445 : :
446 [ # # # ]: 0 : switch ( m_eType )
447 : : {
448 : : case FORM:
449 : : case REPORT:
450 [ # # ]: 0 : impl_saveSubDocument_throw( xObjectStor );
451 : 0 : break;
452 : :
453 : : case QUERY:
454 [ # # ]: 0 : impl_saveQueryDesign_throw( xObjectStor );
455 : 0 : break;
456 : :
457 : : default:
458 : : // TODO
459 : : OSL_FAIL( "SubComponentRecoverys::saveToRecoveryStorage: unimplemented case!" );
460 : 0 : break;
461 : : }
462 : :
463 : : // commit the storage(s)
464 [ # # ]: 0 : tools::stor::commitStorageIfWriteable( xObjectStor );
465 [ # # ]: 0 : tools::stor::commitStorageIfWriteable( xComponentsStorage );
466 : :
467 : : // remember the relationship from the component name to the storage name
468 [ # # ]: 0 : MapStringToCompDesc& rMapCompDescs = io_mapCompDescs[ m_eType ];
469 : : OSL_ENSURE( rMapCompDescs.find( sStorName ) == rMapCompDescs.end(),
470 : : "SubComponentRecoverys::saveToRecoveryStorage: object name already used!" );
471 [ # # ]: 0 : rMapCompDescs[ sStorName ] = m_aCompDesc;
472 : : }
473 : :
474 : : //--------------------------------------------------------------------
475 : 0 : void SubComponentRecovery::impl_identifyComponent_throw()
476 : : {
477 : : // ask the controller
478 [ # # ][ # # ]: 0 : Pair< sal_Int32, ::rtl::OUString > aComponentIdentity = m_xDocumentUI->identifySubComponent( m_xComponent );
479 : 0 : m_eType = lcl_databaseObjectToSubComponentType( aComponentIdentity.First );
480 : 0 : m_aCompDesc.sName = aComponentIdentity.Second;
481 : :
482 : : // what the controller didn't give us is the information whether this is in edit mode or not ...
483 [ # # ][ # # ]: 0 : Reference< XModuleManager > xModuleManager( m_rContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW );
484 [ # # ][ # # ]: 0 : const ::rtl::OUString sModuleIdentifier = xModuleManager->identify( m_xComponent );
485 : :
486 [ # # # # : 0 : switch ( m_eType )
# ]
487 : : {
488 : : case TABLE:
489 : 0 : m_aCompDesc.bForEditing = sModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.sdb.TableDesign" ) );
490 : 0 : break;
491 : :
492 : : case QUERY:
493 : 0 : m_aCompDesc.bForEditing = sModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.sdb.QueryDesign" ) );
494 : 0 : break;
495 : :
496 : : case REPORT:
497 [ # # ]: 0 : if ( sModuleIdentifier == "com.sun.star.report.ReportDefinition" )
498 : : {
499 : : // it's an SRB report designer
500 : 0 : m_aCompDesc.bForEditing = true;
501 : 0 : break;
502 : : }
503 : : // fall through
504 : :
505 : : case FORM:
506 [ # # ]: 0 : m_aCompDesc.bForEditing = !lcl_determineReadOnly( m_xComponent );
507 : 0 : break;
508 : :
509 : : default:
510 [ # # ]: 0 : if ( sModuleIdentifier == "com.sun.star.sdb.RelationDesign" )
511 : : {
512 : 0 : m_eType = RELATION_DESIGN;
513 : 0 : m_aCompDesc.bForEditing = true;
514 : : }
515 : : else
516 : : {
517 : : OSL_FAIL( "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the given sub component!" );
518 : : }
519 : 0 : break;
520 : : }
521 : :
522 : : OSL_POSTCOND( m_eType != UNKNOWN,
523 : 0 : "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the component!" );
524 : 0 : }
525 : :
526 : : //--------------------------------------------------------------------
527 : 0 : void SubComponentRecovery::impl_saveQueryDesign_throw( const Reference< XStorage >& i_rObjectStorage )
528 : : {
529 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( m_eType == QUERY, "illegal sub component type" );
[ # # ][ # # ]
530 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" );
[ # # ][ # # ]
531 : :
532 : : // retrieve the current query design (which might differ from what we can retrieve as ActiveCommand property, since
533 : : // the latter is updated only upon successful save of the design)
534 [ # # ]: 0 : Reference< XPropertySet > xDesignerProps( m_xComponent, UNO_QUERY_THROW );
535 [ # # ]: 0 : Sequence< PropertyValue > aCurrentQueryDesign;
536 [ # # ][ # # ]: 0 : OSL_VERIFY( xDesignerProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ) ) >>= aCurrentQueryDesign );
[ # # ][ # # ]
537 : :
538 : : // write the query design
539 [ # # ][ # # ]: 0 : StorageXMLOutputStream aDesignOutput( m_rContext, i_rObjectStorage, lcl_getSettingsStreamName() );
540 [ # # ]: 0 : SettingsExportContext aSettingsExportContext( m_rContext, aDesignOutput );
541 : :
542 [ # # ]: 0 : const ::rtl::OUString sWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
543 : :
544 [ # # ][ # # ]: 0 : aDesignOutput.startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "office:settings" ) ) );
545 [ # # ]: 0 : aDesignOutput.ignorableWhitespace( sWhitespace );
546 : :
547 [ # # ]: 0 : XMLSettingsExportHelper aSettingsExporter( aSettingsExportContext );
548 [ # # ][ # # ]: 0 : aSettingsExporter.exportAllSettings( aCurrentQueryDesign, lcl_getCurrentQueryDesignName() );
549 : :
550 [ # # ]: 0 : aDesignOutput.ignorableWhitespace( sWhitespace );
551 [ # # ]: 0 : aDesignOutput.endElement();
552 [ # # ][ # # ]: 0 : aDesignOutput.close();
[ # # ][ # # ]
553 : 0 : }
554 : :
555 : : //--------------------------------------------------------------------
556 : 0 : void SubComponentRecovery::impl_saveSubDocument_throw( const Reference< XStorage >& i_rObjectStorage )
557 : : {
558 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( ( m_eType == FORM ) || ( m_eType == REPORT ), "illegal sub component type" );
[ # # ][ # # ]
[ # # ]
559 [ # # ][ # # ]: 0 : ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" );
[ # # ][ # # ]
560 : :
561 : : // store the document into the storage
562 [ # # ]: 0 : Reference< XStorageBasedDocument > xStorageDocument( m_xComponent, UNO_QUERY_THROW );
563 [ # # ][ # # ]: 0 : xStorageDocument->storeToStorage( i_rObjectStorage, Sequence< PropertyValue >() );
[ # # ][ # # ]
564 : 0 : }
565 : :
566 : : //--------------------------------------------------------------------
567 : 0 : Reference< XComponent > SubComponentRecovery::impl_recoverSubDocument_throw( const Reference< XStorage >& i_rRecoveryStorage,
568 : : const ::rtl::OUString& i_rComponentName, const bool i_bForEditing )
569 : : {
570 : 0 : Reference< XComponent > xSubComponent;
571 : 0 : Reference< XCommandProcessor > xDocDefinition;
572 : :
573 [ # # ]: 0 : ::comphelper::NamedValueCollection aLoadArgs;
574 [ # # ]: 0 : aLoadArgs.put( "RecoveryStorage", i_rRecoveryStorage );
575 : :
576 : : // load/create the sub component hidden. We'll show it when the main app window is shown.
577 [ # # ]: 0 : aLoadArgs.put( "Hidden", true );
578 : :
579 [ # # ]: 0 : if ( !i_rComponentName.isEmpty() )
580 : : {
581 [ # # ][ # # ]: 0 : xDocDefinition = lcl_getSubComponentDef_nothrow( m_xDocumentUI, m_eType, i_rComponentName );
582 [ # # ]: 0 : xSubComponent.set( m_xDocumentUI->loadComponentWithArguments(
583 : : m_eType,
584 : : i_rComponentName,
585 : : i_bForEditing,
586 : : aLoadArgs.getPropertyValues()
587 : 0 : ),
588 : : UNO_SET_THROW
589 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
590 : : }
591 : : else
592 : : {
593 : 0 : Reference< XComponent > xDocDefComponent;
594 [ # # ]: 0 : xSubComponent.set( m_xDocumentUI->createComponentWithArguments(
595 : : m_eType,
596 : : aLoadArgs.getPropertyValues(),
597 : : xDocDefComponent
598 : 0 : ),
599 : : UNO_SET_THROW
600 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
601 : :
602 [ # # ]: 0 : xDocDefinition.set( xDocDefComponent, UNO_QUERY );
603 : 0 : OSL_ENSURE( xDocDefinition.is(), "DatabaseDocumentRecovery::recoverSubDocuments: loaded a form/report, but don't have a document definition?!" );
604 : : }
605 : :
606 [ # # ]: 0 : if ( xDocDefinition.is() )
607 : : {
608 [ # # ]: 0 : Reference< XController > xController( m_xDocumentUI, UNO_QUERY_THROW );
609 [ # # ][ # # ]: 0 : Reference< XInterface > xLoader( *new SubComponentLoader( xController, xDocDefinition ) );
610 : 0 : (void)xLoader;
611 : : }
612 : :
613 [ # # ]: 0 : return xSubComponent;
614 : : }
615 : :
616 : : //--------------------------------------------------------------------
617 : 0 : Reference< XComponent > SubComponentRecovery::impl_recoverQueryDesign_throw( const Reference< XStorage >& i_rRecoveryStorage,
618 : : const ::rtl::OUString& i_rComponentName, const bool i_bForEditing )
619 : : {
620 : 0 : Reference< XComponent > xSubComponent;
621 : :
622 : : // first read the settings query design settings from the storage
623 [ # # ][ # # ]: 0 : StorageXMLInputStream aDesignInput( m_rContext, i_rRecoveryStorage, lcl_getSettingsStreamName() );
624 : :
625 [ # # ]: 0 : ::rtl::Reference< SettingsDocumentHandler > pDocHandler( new SettingsDocumentHandler );
626 [ # # ][ # # ]: 0 : aDesignInput.import( pDocHandler.get() );
[ # # ]
627 : :
628 : 0 : const ::comphelper::NamedValueCollection& rSettings( pDocHandler->getSettings() );
629 [ # # ][ # # ]: 0 : const Any aCurrentQueryDesign = rSettings.get( lcl_getCurrentQueryDesignName() );
630 : : #if OSL_DEBUG_LEVEL > 0
631 : : Sequence< PropertyValue > aQueryDesignLayout;
632 : : OSL_VERIFY( aCurrentQueryDesign >>= aQueryDesignLayout );
633 : : #endif
634 : :
635 : : // then load the query designer
636 [ # # ]: 0 : ::comphelper::NamedValueCollection aLoadArgs;
637 [ # # ]: 0 : aLoadArgs.put( "CurrentQueryDesign", aCurrentQueryDesign );
638 [ # # ]: 0 : aLoadArgs.put( "Hidden", true );
639 : :
640 [ # # ]: 0 : if ( !i_rComponentName.isEmpty() )
641 : : {
642 [ # # ]: 0 : xSubComponent.set( m_xDocumentUI->loadComponentWithArguments(
643 : : m_eType,
644 : : i_rComponentName,
645 : : i_bForEditing,
646 : : aLoadArgs.getPropertyValues()
647 : 0 : ),
648 : : UNO_SET_THROW
649 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
650 : : }
651 : : else
652 : : {
653 : 0 : Reference< XComponent > xDummy;
654 [ # # ]: 0 : xSubComponent.set( m_xDocumentUI->createComponentWithArguments(
655 : : m_eType,
656 : : aLoadArgs.getPropertyValues(),
657 : : xDummy
658 : 0 : ),
659 : : UNO_SET_THROW
660 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
661 : : }
662 : :
663 [ # # ]: 0 : Reference< XController > xController( m_xDocumentUI, UNO_QUERY_THROW );
664 [ # # ][ # # ]: 0 : Reference< XInterface > xLoader( *new SubComponentLoader( xController, xSubComponent ) );
665 : : (void)xLoader;
666 : :
667 [ # # ][ # # ]: 0 : return xSubComponent;
668 : : }
669 : :
670 : : //--------------------------------------------------------------------
671 : 0 : Reference< XComponent > SubComponentRecovery::recoverFromStorage( const Reference< XStorage >& i_rRecoveryStorage,
672 : : const ::rtl::OUString& i_rComponentName, const bool i_bForEditing )
673 : : {
674 : 0 : Reference< XComponent > xSubComponent;
675 [ # # # ]: 0 : switch ( m_eType )
676 : : {
677 : : case FORM:
678 : : case REPORT:
679 [ # # ][ # # ]: 0 : xSubComponent = impl_recoverSubDocument_throw( i_rRecoveryStorage, i_rComponentName, i_bForEditing );
680 : 0 : break;
681 : : case QUERY:
682 [ # # ][ # # ]: 0 : xSubComponent = impl_recoverQueryDesign_throw( i_rRecoveryStorage, i_rComponentName, i_bForEditing );
683 : 0 : break;
684 : : default:
685 : : OSL_FAIL( "SubComponentRecovery::recoverFromStorage: unimplemented case!" );
686 : 0 : break;
687 : : }
688 : 0 : return xSubComponent;
689 : : }
690 : :
691 : : //........................................................................
692 : : } // namespace dbaccess
693 : : //........................................................................
694 : :
695 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|