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>
49 using css::uno::Reference;
50 using css::uno::UNO_QUERY;
51 using css::uno::UNO_QUERY_THROW;
52 using css::uno::UNO_SET_THROW;
53 using css::uno::Exception;
55 using css::uno::Sequence;
56 using css::uno::XComponentContext;
57 using css::embed::XStorage;
58 using css::sdb::application::XDatabaseDocumentUI;
59 using css::beans::Pair;
60 using css::frame::ModuleManager;
61 using css::frame::XModuleManager2;
62 using css::lang::XComponent;
63 using css::frame::XModel;
64 using css::frame::XController;
65 using css::beans::XPropertySet;
66 using css::beans::PropertyValue;
67 using css::document::XStorageBasedDocument;
68 using css::ucb::XCommandProcessor;
69 using css::container::XHierarchicalNameAccess;
70 using css::sdb::XFormDocumentsSupplier;
71 using css::sdb::XReportDocumentsSupplier;
72 using css::xml::sax::XLocator;
73 using css::xml::sax::XDocumentHandler;
74 using css::xml::sax::XAttributeList;
76 namespace ElementModes = css::embed::ElementModes;
77 namespace DatabaseObject = css::sdb::application::DatabaseObject;
98 OSL_FAIL(
"lcl_getComponentStorageBaseName: unimplemented case!" );
102 SubComponentType lcl_databaseObjectToSubComponentType(
const sal_Int32 i_nObjectType )
104 switch ( i_nObjectType )
108 case DatabaseObject::FORM:
return FORM;
116 bool lcl_determineReadOnly(
const Reference< XComponent >& i_rComponent )
118 Reference< XModel > xDocument( i_rComponent, UNO_QUERY );
119 if ( !xDocument.is() )
121 Reference< XController >
xController( i_rComponent, UNO_QUERY_THROW );
125 if ( !xDocument.is() )
129 return aDocArgs.getOrDefault(
"ReadOnly",
false );
132 Reference< XCommandProcessor > lcl_getSubComponentDef_nothrow(
const Reference< XDatabaseDocumentUI >& i_rAppUI,
135 Reference< XController >
xController( i_rAppUI, UNO_QUERY_THROW );
136 ENSURE_OR_RETURN( ( i_eType ==
FORM ) || ( i_eType ==
REPORT ),
"lcl_getSubComponentDef_nothrow: illegal controller",
nullptr );
138 Reference< XCommandProcessor > xCommandProcessor;
141 Reference< XHierarchicalNameAccess > xDefinitionContainer;
142 if ( i_eType ==
FORM )
144 Reference< XFormDocumentsSupplier > xSuppForms(
xController->getModel(), UNO_QUERY_THROW );
145 xDefinitionContainer.set( xSuppForms->getFormDocuments(), UNO_QUERY_THROW );
149 Reference< XReportDocumentsSupplier > xSuppReports(
xController->getModel(), UNO_QUERY_THROW );
150 xDefinitionContainer.set( xSuppReports->getReportDocuments(), UNO_QUERY_THROW );
152 xCommandProcessor.set( xDefinitionContainer->getByHierarchicalName( i_rName ), UNO_QUERY_THROW );
154 catch(
const Exception& )
158 return xCommandProcessor;
161 constexpr OUStringLiteral sSettingsStreamName =
u"settings.xml";
162 constexpr OUStringLiteral sCurrentQueryDesignName =
u"ooo:current-query-design";
171 SettingsExportContext(
const Reference<XComponentContext>& i_rContext, StorageXMLOutputStream& i_rDelegator )
178 virtual ~SettingsExportContext()
183 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
const OUString& i_rValue )
override;
184 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue )
override;
185 virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName )
override;
186 virtual void EndElement (
const bool i_bIgnoreWhitespace )
override;
187 virtual void Characters(
const OUString& i_rCharacters )
override;
189 virtual css::uno::Reference< css::uno::XComponentContext >
190 GetComponentContext()
const override;
193 OUString impl_prefix( const ::xmloff::token::XMLTokenEnum i_eToken )
195 return m_aNamespace +
":" + ::xmloff::token::GetXMLToken( i_eToken );
206 void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
const OUString& i_rValue )
211 void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue )
216 void SettingsExportContext::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName )
223 void SettingsExportContext::EndElement(
const bool i_bIgnoreWhitespace )
225 if ( i_bIgnoreWhitespace )
230 void SettingsExportContext::Characters(
const OUString& i_rCharacters )
235 Reference< css::uno::XComponentContext > SettingsExportContext::GetComponentContext()
const
241 typedef ::cppu::WeakImplHelper< XDocumentHandler
249 SettingsDocumentHandler()
254 virtual ~SettingsDocumentHandler()
override
260 virtual void SAL_CALL startDocument( )
override;
261 virtual void SAL_CALL endDocument( )
override;
262 virtual void SAL_CALL startElement(
const OUString&
aName,
const Reference< XAttributeList >& xAttribs )
override;
263 virtual void SAL_CALL endElement(
const OUString&
aName )
override;
264 virtual void SAL_CALL characters(
const OUString& aChars )
override;
265 virtual void SAL_CALL ignorableWhitespace(
const OUString& aWhitespaces )
override;
266 virtual void SAL_CALL processingInstruction(
const OUString& aTarget,
const OUString&
aData )
override;
267 virtual void SAL_CALL setDocumentLocator(
const Reference< XLocator >& xLocator )
override;
269 const ::comphelper::NamedValueCollection& getSettings()
const {
return m_aSettings; }
272 std::stack< ::rtl::Reference< SettingsImport > >
m_aStates;
278 void SAL_CALL SettingsDocumentHandler::startDocument( )
282 void SAL_CALL SettingsDocumentHandler::endDocument( )
286 void SAL_CALL SettingsDocumentHandler::startElement(
const OUString& i_Name,
const Reference< XAttributeList >& i_Attribs )
292 if ( i_Name ==
"office:settings" )
294 pNewState =
new OfficeSettingsImport(
m_aSettings );
298 OSL_FAIL(
"SettingsDocumentHandler::startElement: invalid settings file!" );
308 pNewState = pCurrentState->nextState( i_Name );
312 pNewState->startElement( i_Attribs );
317 void SAL_CALL SettingsDocumentHandler::endElement(
const OUString& )
322 pCurrentState->endElement();
326 void SAL_CALL SettingsDocumentHandler::characters(
const OUString& i_Chars )
331 pCurrentState->characters( i_Chars );
334 void SAL_CALL SettingsDocumentHandler::ignorableWhitespace(
const OUString& )
339 void SAL_CALL SettingsDocumentHandler::processingInstruction(
const OUString&,
const OUString& )
341 OSL_FAIL(
"SettingsDocumentHandler::processingInstruction: unexpected ..." );
344 void SAL_CALL SettingsDocumentHandler::setDocumentLocator(
const Reference< XLocator >& ) {}
365 OSL_FAIL(
"SubComponentRecovery::getComponentsStorageName: unimplemented case!" );
378 const Reference< XStorage > xComponentsStorage( i_rRecoveryStorage->openStorageElement(
379 rStorageName, ElementModes::READWRITE ), UNO_SET_THROW );
382 const OUString& rBaseName( lcl_getComponentStorageBaseName(
m_eType ) );
383 const OUString sStorName = ::dbtools::createUniqueName( xComponentsStorage, rBaseName );
384 const Reference< XStorage > xObjectStor( xComponentsStorage->openStorageElement(
385 sStorName, ElementModes::READWRITE ), UNO_SET_THROW );
400 OSL_FAIL(
"SubComponentRecoverys::saveToRecoveryStorage: unimplemented case!" );
410 OSL_ENSURE( rMapCompDescs.find( sStorName ) == rMapCompDescs.end(),
411 "SubComponentRecoverys::saveToRecoveryStorage: object name already used!" );
419 m_eType = lcl_databaseObjectToSubComponentType( aComponentIdentity.First );
423 Reference< XModuleManager2 > xModuleManager( ModuleManager::create(
m_rContext) );
424 const OUString sModuleIdentifier = xModuleManager->identify(
m_xComponent );
437 if ( sModuleIdentifier ==
"com.sun.star.report.ReportDefinition" )
450 if ( sModuleIdentifier ==
"com.sun.star.sdb.RelationDesign" )
457 OSL_FAIL(
"SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the given sub component!" );
463 "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the component!" );
473 Reference< XPropertySet > xDesignerProps(
m_xComponent, UNO_QUERY_THROW );
474 Sequence< PropertyValue > aCurrentQueryDesign;
475 OSL_VERIFY( xDesignerProps->getPropertyValue(
"CurrentQueryDesign" ) >>= aCurrentQueryDesign );
479 SettingsExportContext aSettingsExportContext(
m_rContext, aDesignOutput );
481 static constexpr OUStringLiteral sWhitespace(
u" " );
487 aSettingsExporter.
exportAllSettings( aCurrentQueryDesign, sCurrentQueryDesignName );
491 aDesignOutput.
close();
500 Reference< XStorageBasedDocument > xStorageDocument(
m_xComponent, UNO_QUERY_THROW );
501 xStorageDocument->storeToStorage( i_rObjectStorage, Sequence< PropertyValue >() );
505 const OUString& i_rComponentName,
const bool i_bForEditing )
507 Reference< XComponent > xSubComponent;
508 Reference< XCommandProcessor > xDocDefinition;
511 aLoadArgs.
put(
"RecoveryStorage", i_rRecoveryStorage );
514 aLoadArgs.
put(
"Hidden",
true );
516 if ( !i_rComponentName.isEmpty() )
519 xSubComponent.set(
m_xDocumentUI->loadComponentWithArguments(
530 Reference< XComponent > xDocDefComponent;
531 xSubComponent.set(
m_xDocumentUI->createComponentWithArguments(
539 xDocDefinition.set( xDocDefComponent, UNO_QUERY );
540 OSL_ENSURE( xDocDefinition.is(),
"DatabaseDocumentRecovery::recoverSubDocuments: loaded a form/report, but don't have a document definition?!" );
543 if ( xDocDefinition.is() )
549 return xSubComponent;
553 const OUString& i_rComponentName,
const bool i_bForEditing )
555 Reference< XComponent > xSubComponent;
561 aDesignInput.
import( pDocHandler );
563 const ::comphelper::NamedValueCollection& rSettings( pDocHandler->getSettings() );
564 const Any& aCurrentQueryDesign = rSettings.get( sCurrentQueryDesignName );
565#if OSL_DEBUG_LEVEL > 0
566 Sequence< PropertyValue > aQueryDesignLayout;
567 OSL_VERIFY( aCurrentQueryDesign >>= aQueryDesignLayout );
572 aLoadArgs.
put(
"CurrentQueryDesign", aCurrentQueryDesign );
573 aLoadArgs.
put(
"Hidden",
true );
575 if ( !i_rComponentName.isEmpty() )
577 xSubComponent.set(
m_xDocumentUI->loadComponentWithArguments(
588 Reference< XComponent > xDummy;
589 xSubComponent.set(
m_xDocumentUI->createComponentWithArguments(
601 return xSubComponent;
605 const OUString& i_rComponentName,
const bool i_bForEditing )
607 Reference< XComponent > xSubComponent;
618 OSL_FAIL(
"SubComponentRecovery::recoverFromStorage: unimplemented case!" );
621 return xSubComponent;
void exportAllSettings(const css::uno::Sequence< css::beans::PropertyValue > &aProps, const OUString &rName) const
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
void startElement(const OUString &i_rElementName)
void characters(const OUString &i_rCharacters) const
void addAttribute(const OUString &i_rName, const OUString &i_rValue) const
void ignorableWhitespace(const OUString &i_rWhitespace) const
is a helper class which loads/opens a given sub component as soon as the main application window beco...
void impl_saveSubDocument_throw(const css::uno::Reference< css::embed::XStorage > &i_rObjectStorage)
css::uno::Reference< css::lang::XComponent > impl_recoverQueryDesign_throw(const css::uno::Reference< css::embed::XStorage > &i_rRecoveryStorage, const OUString &i_rComponentName, const bool i_bForEditing)
const css::uno::Reference< css::uno::XComponentContext > & m_rContext
css::uno::Reference< css::lang::XComponent > recoverFromStorage(const css::uno::Reference< css::embed::XStorage > &i_rRecoveryStorage, const OUString &i_rComponentName, const bool i_bForEditing)
css::uno::Reference< css::lang::XComponent > impl_recoverSubDocument_throw(const css::uno::Reference< css::embed::XStorage > &i_rRecoveryStorage, const OUString &i_rComponentName, const bool i_bForEditing)
const css::uno::Reference< css::lang::XComponent > m_xComponent
static OUString getComponentsStorageName(const SubComponentType i_eType)
void saveToRecoveryStorage(const css::uno::Reference< css::embed::XStorage > &i_rRecoveryStorage, MapCompTypeToCompDescs &io_mapCompDescs)
void impl_identifyComponent_throw()
css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > m_xDocumentUI
void impl_saveQueryDesign_throw(const css::uno::Reference< css::embed::XStorage > &i_rObjectStorage)
SubComponentDescriptor m_aCompDesc
#define ENSURE_OR_THROW(c, m)
#define ENSURE_OR_RETURN(c, m, r)
#define DBG_UNHANDLED_EXCEPTION(...)
#define SAL_WARN_IF(condition, area, stream)
constexpr OUStringLiteral aData
std::unordered_map< OUString, SubComponentDescriptor > MapStringToCompDesc
std::map< SubComponentType, MapStringToCompDesc > MapCompTypeToCompDescs
::cppu::WeakImplHelper< XDocumentHandler > SettingsDocumentHandler_Base
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
Reference< XController > xController
the controller of the sub component. Must not be <NULL>
::comphelper::NamedValueCollection m_aSettings
StorageXMLOutputStream & m_rDelegator
const OUString m_aNamespace
const Reference< XComponentContext > & m_rContext
std::stack< ::rtl::Reference< SettingsImport > > m_aStates