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