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