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