xref: /core/dbaccess/source/filter/xml/xmlExport.cxx (revision b47bca7f)
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 "xmlExport.hxx"
21 #include "xmlAutoStyle.hxx"
22 #include "xmlservices.hxx"
23 #include <flt_reghelper.hxx>
24 #include <sax/tools/converter.hxx>
25 #include <xmloff/ProgressBarHelper.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/txtimp.hxx>
28 #include <xmloff/xmlnmspe.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <comphelper/sequence.hxx>
32 #include <comphelper/string.hxx>
33 #include <comphelper/types.hxx>
34 #include <stringconstants.hxx>
35 #include <strings.hxx>
36 #include <sal/log.hxx>
37 #include "xmlEnums.hxx"
38 #include <com/sun/star/beans/XPropertyState.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
41 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
42 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
43 #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
44 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
45 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
46 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
47 
48 #include <com/sun/star/awt/TextAlign.hpp>
49 #include <xmloff/xmluconv.hxx>
50 #include "xmlHelper.hxx"
51 #include <com/sun/star/awt/FontDescriptor.hpp>
52 #include <svl/filenotation.hxx>
53 #include <unotools/pathoptions.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <connectivity/DriversConfig.hxx>
56 #include <connectivity/dbtools.hxx>
57 
58 #include <boost/optional.hpp>
59 #include <memory>
60 #include <iterator>
61 
62 using namespace comphelper;
63 using namespace ::com::sun::star::sdb;
64 using namespace ::com::sun::star::sdbcx;
65 using namespace ::com::sun::star::util;
66 using namespace ::com::sun::star;
67 
68 namespace dbaxml
69 {
70     class ODBExportHelper
71     {
72     public:
73         /// @throws RuntimeException
74         static OUString getImplementationName_Static(  );
75         /// @throws RuntimeException
76         static Sequence< OUString > getSupportedServiceNames_Static(  );
77         static Reference< XInterface > Create(const Reference< css::lang::XMultiServiceFactory >&);
78     };
79     class ODBFullExportHelper
80     {
81     public:
82         /// @throws RuntimeException
83         static OUString getImplementationName_Static(  );
84         /// @throws RuntimeException
85         static Sequence< OUString > getSupportedServiceNames_Static(  );
86         static Reference< XInterface > Create(const Reference< css::lang::XMultiServiceFactory >&);
87     };
88 }
89 
90 extern "C" void createRegistryInfo_ODBFilterExport( )
91 {
92     static ::dbaxml::OMultiInstanceAutoRegistration< ::dbaxml::ODBExport > aAutoRegistration;
93 }
94 
95 extern "C" void createRegistryInfo_OSettingsExport( )
96 
97 {
98     static ::dbaxml::OMultiInstanceAutoRegistration< ::dbaxml::ODBExportHelper > aAutoRegistration;
99 }
100 
101 extern "C" void createRegistryInfo_OFullExport( )
102 {
103     static ::dbaxml::OMultiInstanceAutoRegistration< ::dbaxml::ODBFullExportHelper > aAutoRegistration;
104 }
105 
106 namespace dbaxml
107 {
108     Reference< XInterface > ODBExportHelper::Create(const Reference< XMultiServiceFactory >& _rxORB)
109     {
110         return static_cast< XServiceInfo* >(new ODBExport(comphelper::getComponentContext(_rxORB), getImplementationName_Static(), SvXMLExportFlags::SETTINGS | SvXMLExportFlags::PRETTY ));
111     }
112 
113     OUString ODBExportHelper::getImplementationName_Static(  )
114     {
115         return OUString("com.sun.star.comp.sdb.XMLSettingsExporter");
116     }
117 
118     Sequence< OUString > ODBExportHelper::getSupportedServiceNames_Static(  )
119     {
120         Sequence< OUString > aSupported { "com.sun.star.document.ExportFilter" };
121         return aSupported;
122     }
123 
124     Reference< XInterface > ODBFullExportHelper::Create(const Reference< XMultiServiceFactory >& _rxORB)
125     {
126         return static_cast< XServiceInfo* >(new ODBExport(comphelper::getComponentContext(_rxORB), getImplementationName_Static(), SvXMLExportFlags::ALL));
127     }
128     OUString ODBFullExportHelper::getImplementationName_Static(  )
129     {
130         return OUString("com.sun.star.comp.sdb.XMLFullExporter");
131     }
132     Sequence< OUString > ODBFullExportHelper::getSupportedServiceNames_Static(  )
133     {
134         Sequence< OUString > aSupported { "com.sun.star.document.ExportFilter" };
135         return aSupported;
136     }
137 
138     static OUString lcl_implGetPropertyXMLType(const Type& _rType)
139     {
140         // possible types we can write (either because we recognize them directly or because we convert _rValue
141         // into one of these types)
142 
143         // handle the type description
144         switch (_rType.getTypeClass())
145         {
146             case TypeClass_STRING:
147                 return OUString("string");
148             case TypeClass_DOUBLE:
149                 return OUString("double");
150             case TypeClass_BOOLEAN:
151                 return OUString("boolean");
152             case TypeClass_BYTE:
153             case TypeClass_SHORT:
154                 return OUString("short");
155             case TypeClass_LONG:
156                 return OUString("int");
157             case TypeClass_HYPER:
158                 return OUString("long");
159             case TypeClass_ENUM:
160                 return OUString("int");
161 
162             default:
163                 OSL_FAIL( "lcl_implGetPropertyXMLType: unsupported value type!" );
164                 return OUString("double");
165         }
166     }
167 
168     class OSpecialHandleXMLExportPropertyMapper : public SvXMLExportPropertyMapper
169     {
170     public:
171         explicit OSpecialHandleXMLExportPropertyMapper(const rtl::Reference< XMLPropertySetMapper >& rMapper) : SvXMLExportPropertyMapper(rMapper )
172         {
173         }
174         /** this method is called for every item that has the
175         MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
176         virtual void handleSpecialItem(
177                 SvXMLAttributeList& /*rAttrList*/,
178                 const XMLPropertyState& /*rProperty*/,
179                 const SvXMLUnitConverter& /*rUnitConverter*/,
180                 const SvXMLNamespaceMap& /*rNamespaceMap*/,
181                 const std::vector< XMLPropertyState > * /*pProperties*/ ,
182                 sal_uInt32 /*nIdx*/ ) const override
183         {
184             // nothing to do here
185         }
186     };
187 ODBExport::ODBExport(const Reference< XComponentContext >& _rxContext, OUString const & implementationName, SvXMLExportFlags nExportFlag)
188 : SvXMLExport( util::MeasureUnit::MM_10TH, _rxContext, implementationName, XML_DATABASE,
189         SvXMLExportFlags::OASIS | nExportFlag)
190 ,m_aTypeCollection(_rxContext)
191 ,m_bAllreadyFilled(false)
192 {
193     GetMM100UnitConverter().SetCoreMeasureUnit(util::MeasureUnit::MM_10TH);
194     GetMM100UnitConverter().SetXMLMeasureUnit(util::MeasureUnit::CM);
195 
196     GetNamespaceMap_().Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
197     GetNamespaceMap_().Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
198     GetNamespaceMap_().Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG), XML_NAMESPACE_SVG );
199 
200     GetNamespaceMap_().Add( GetXMLToken(XML_NP_DB), GetXMLToken(XML_N_DB_OASIS), XML_NAMESPACE_DB );
201 
202     if( nExportFlag & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) )
203         GetNamespaceMap_().Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
204 
205     if( nExportFlag & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) )
206     {
207         GetNamespaceMap_().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
208     }
209     if( nExportFlag & SvXMLExportFlags::SETTINGS )
210     {
211         GetNamespaceMap_().Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
212     }
213 
214     if( nExportFlag & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) )
215     {
216         GetNamespaceMap_().Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
217     }
218 
219     GetNamespaceMap_().Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
220     GetNamespaceMap_().Add( GetXMLToken(XML_NP_NUMBER), GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
221 
222     m_xExportHelper = new SvXMLExportPropertyMapper(GetTableStylesPropertySetMapper());
223     m_xColumnExportHelper = new OSpecialHandleXMLExportPropertyMapper(GetColumnStylesPropertySetMapper());
224 
225     m_xCellExportHelper = new OSpecialHandleXMLExportPropertyMapper(GetCellStylesPropertySetMapper());
226     m_xRowExportHelper = new OSpecialHandleXMLExportPropertyMapper(OXMLHelper::GetRowStylesPropertySetMapper());
227 
228     GetAutoStylePool()->AddFamily(
229         XML_STYLE_FAMILY_TABLE_TABLE,
230         OUString(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME ),
231         m_xExportHelper.get(),
232         OUString(XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX ));
233 
234     GetAutoStylePool()->AddFamily(
235         XML_STYLE_FAMILY_TABLE_COLUMN,
236         OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME ),
237         m_xColumnExportHelper.get(),
238         OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX ));
239 
240     GetAutoStylePool()->AddFamily(
241         XML_STYLE_FAMILY_TABLE_CELL,
242         OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME ),
243         m_xCellExportHelper.get(),
244         OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX ));
245 
246     GetAutoStylePool()->AddFamily(
247         XML_STYLE_FAMILY_TABLE_ROW,
248         OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME ),
249         m_xRowExportHelper.get(),
250         OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX ));
251 }
252 
253 OUString ODBExport::getImplementationName_Static()
254 {
255     return OUString("com.sun.star.comp.sdb.DBExportFilter");
256 }
257 
258 css::uno::Sequence<OUString> ODBExport::getSupportedServiceNames_Static()
259 {
260     css::uno::Sequence<OUString> s { "com.sun.star.document.ExportFilter" };
261     return s;
262 }
263 
264 css::uno::Reference< css::uno::XInterface >
265     ODBExport::Create(const css::uno::Reference< css::lang::XMultiServiceFactory >& _rxORB)
266 {
267     return static_cast< XServiceInfo* >(new ODBExport( comphelper::getComponentContext(_rxORB), getImplementationName_Static()));
268 }
269 
270 void ODBExport::exportDataSource()
271 {
272     try
273     {
274         Reference<XPropertySet> xProp( getDataSource(), UNO_SET_THROW );
275 
276         bool bAutoIncrementEnabled = true;
277         TStringPair aAutoIncrement;
278 
279         Reference< XPropertySet > xDataSourceSettings;
280         OSL_VERIFY( xProp->getPropertyValue( PROPERTY_SETTINGS ) >>= xDataSourceSettings );
281         Reference< XPropertyState > xSettingsState( xDataSourceSettings, UNO_QUERY_THROW );
282         Reference< XPropertySetInfo > xSettingsInfo( xDataSourceSettings->getPropertySetInfo(), UNO_SET_THROW );
283 
284         TDelimiter aDelimiter;
285         xSettingsState->getPropertyDefault( INFO_TEXTDELIMITER ) >>= aDelimiter.sText;
286         xSettingsState->getPropertyDefault( INFO_FIELDDELIMITER ) >>= aDelimiter.sField;
287         xSettingsState->getPropertyDefault( INFO_DECIMALDELIMITER ) >>= aDelimiter.sDecimal;
288         xSettingsState->getPropertyDefault( INFO_THOUSANDSDELIMITER ) >>= aDelimiter.sThousand;
289 
290         ::connectivity::DriversConfig aDriverConfig(getComponentContext());
291         const OUString sURL = ::comphelper::getString(xProp->getPropertyValue(PROPERTY_URL));
292         const ::comphelper::NamedValueCollection& aDriverSupportedProperties( aDriverConfig.getProperties( sURL ) );
293 
294         static OUString s_sTrue(::xmloff::token::GetXMLToken( XML_TRUE ));
295         static OUString s_sFalse(::xmloff::token::GetXMLToken( XML_FALSE ));
296         // loop through the properties, and export only those which are not defaulted
297         TSettingsMap aSettingsMap;
298         Sequence< Property > aProperties = xSettingsInfo->getProperties();
299         const Property* pProperties = aProperties.getConstArray();
300         const Property* pPropertiesEnd = pProperties + aProperties.getLength();
301         for ( ; pProperties != pPropertiesEnd; ++pProperties )
302         {
303             OUString sValue;
304             Any aValue = xDataSourceSettings->getPropertyValue( pProperties->Name );
305             switch ( aValue.getValueTypeClass() )
306             {
307                 case TypeClass_STRING:
308                     aValue >>= sValue;
309                 break;
310                 case TypeClass_DOUBLE:
311                     // let the unit converter format is as string
312                     sValue = OUString::number( getDouble( aValue ) );
313                     break;
314                 case TypeClass_BOOLEAN:
315                     sValue = ::xmloff::token::GetXMLToken( getBOOL( aValue ) ? XML_TRUE : XML_FALSE );
316                     break;
317                 case TypeClass_BYTE:
318                 case TypeClass_SHORT:
319                 case TypeClass_LONG:
320                     // let the unit converter format is as string
321                     sValue = OUString::number( getINT32( aValue ) );
322                     break;
323                 default:
324                     break;
325             }
326 
327             ::xmloff::token::XMLTokenEnum eToken = XML_TOKEN_INVALID;
328 
329             struct PropertyMap
330             {
331                 const OUString                       sPropertyName;
332                 const XMLTokenEnum                          eAttributeToken;
333                 const ::boost::optional< OUString >  aXMLDefault;
334 
335                 PropertyMap( const OUString& _rPropertyName, const XMLTokenEnum _eToken )
336                     :sPropertyName( _rPropertyName )
337                     ,eAttributeToken( _eToken )
338                     ,aXMLDefault()
339                 {
340                 }
341 
342                 PropertyMap( const OUString& _rPropertyName, const XMLTokenEnum _eToken, const OUString& _rDefault )
343                     :sPropertyName( _rPropertyName )
344                     ,eAttributeToken( _eToken )
345                     ,aXMLDefault( _rDefault )
346                 {
347                 }
348             };
349 
350             const PropertyMap aTokens[] =
351             {
352                 PropertyMap( INFO_TEXTFILEHEADER,       XML_IS_FIRST_ROW_HEADER_LINE,       s_sTrue     ),
353                 PropertyMap( INFO_SHOWDELETEDROWS,      XML_SHOW_DELETED,                   s_sFalse    ),
354                 PropertyMap( INFO_ALLOWLONGTABLENAMES,  XML_IS_TABLE_NAME_LENGTH_LIMITED,   s_sTrue     ),
355                 PropertyMap( INFO_ADDITIONALOPTIONS,    XML_SYSTEM_DRIVER_SETTINGS                      ),
356                 PropertyMap( PROPERTY_ENABLESQL92CHECK, XML_ENABLE_SQL92_CHECK,             s_sFalse    ),
357                 PropertyMap( INFO_APPEND_TABLE_ALIAS,   XML_APPEND_TABLE_ALIAS_NAME,        s_sTrue     ),
358                 PropertyMap( INFO_PARAMETERNAMESUBST,   XML_PARAMETER_NAME_SUBSTITUTION,    s_sTrue     ),
359                 PropertyMap( INFO_IGNOREDRIVER_PRIV,    XML_IGNORE_DRIVER_PRIVILEGES,       s_sTrue     ),
360                 PropertyMap( INFO_USECATALOG,           XML_USE_CATALOG,                    s_sFalse    ),
361                 PropertyMap( PROPERTY_SUPPRESSVERSIONCL,XML_SUPPRESS_VERSION_COLUMNS,       s_sTrue     ),
362                 PropertyMap( INFO_CONN_LDAP_BASEDN,     XML_BASE_DN                                     ),
363                 PropertyMap( INFO_CONN_LDAP_ROWCOUNT,   XML_MAX_ROW_COUNT                               )
364             };
365 
366             bool bIsXMLDefault = false;
367             for (const auto & aToken : aTokens)
368             {
369                 if ( pProperties->Name == aToken.sPropertyName )
370                 {
371                     eToken = aToken.eAttributeToken;
372 
373                     if  (   !!aToken.aXMLDefault
374                         &&  ( sValue == *aToken.aXMLDefault )
375                         )
376                     {
377                         bIsXMLDefault = true;
378                     }
379                     break;
380                 }
381             }
382 
383             if ( bIsXMLDefault )
384                 // the property has the value which is specified as default in the XML schema -> no need to write it
385                 continue;
386 
387             if ( eToken == XML_TOKEN_INVALID )
388             {
389                 // for properties which are not REMOVABLE, we care for their state, and
390                 // only export them if they're not DEFAULTed
391                 if ( ( pProperties->Attributes & PropertyAttribute::REMOVABLE ) == 0 )
392                 {
393                     PropertyState ePropertyState = xSettingsState->getPropertyState( pProperties->Name );
394                     if ( PropertyState_DEFAULT_VALUE == ePropertyState )
395                         continue;
396                 }
397 
398                 // special handlings
399                 if ( pProperties->Name == PROPERTY_BOOLEANCOMPARISONMODE )
400                 {
401                     if ( sValue == "0" )
402                         sValue = "equal-integer";
403                     else if ( sValue == "1" )
404                         sValue = "is-boolean";
405                     else if ( sValue == "2" )
406                         sValue = "equal-boolean";
407                     else if ( sValue == "3" )
408                         sValue = "equal-use-only-zero";
409                     if ( sValue == "equal-integer" )
410                         continue;
411                     eToken = XML_BOOLEAN_COMPARISON_MODE;
412                 }
413                 else if ( pProperties->Name == INFO_AUTORETRIEVEENABLED )
414                 {
415                     aValue >>= bAutoIncrementEnabled;
416                     continue;
417                 }
418                 else if ( pProperties->Name == INFO_AUTORETRIEVEVALUE )
419                 {
420                     aAutoIncrement.first = sValue;
421                     continue;
422                 }
423                 else if ( pProperties->Name == PROPERTY_AUTOINCREMENTCREATION )
424                 {
425                     aAutoIncrement.second = sValue;
426                     continue;
427                 }
428                 else if ( pProperties->Name == INFO_TEXTDELIMITER )
429                 {
430                     aDelimiter.sText = sValue;
431                     aDelimiter.bUsed = true;
432                     continue;
433                 }
434                 else if ( pProperties->Name == INFO_FIELDDELIMITER )
435                 {
436                     aDelimiter.sField = sValue;
437                     aDelimiter.bUsed = true;
438                     continue;
439                 }
440                 else if ( pProperties->Name == INFO_DECIMALDELIMITER )
441                 {
442                     aDelimiter.sDecimal = sValue;
443                     aDelimiter.bUsed = true;
444                     continue;
445                 }
446                 else if ( pProperties->Name == INFO_THOUSANDSDELIMITER )
447                 {
448                     aDelimiter.sThousand = sValue;
449                     aDelimiter.bUsed = true;
450                     continue;
451                 }
452                 else if ( pProperties->Name == INFO_CHARSET )
453                 {
454                     m_sCharSet = sValue;
455                     continue;
456                 }
457                 else
458                 {
459                     if ( !aDriverSupportedProperties.has(pProperties->Name) || aDriverSupportedProperties.get(pProperties->Name) != aValue )
460                     {
461                         m_aDataSourceSettings.emplace_back(
462                             pProperties->Name, pProperties->Type, aValue );
463                     }
464                     continue;
465                 }
466             }
467 
468             aSettingsMap.emplace(eToken,sValue);
469         }
470         if ( bAutoIncrementEnabled && !(aAutoIncrement.first.isEmpty() && aAutoIncrement.second.isEmpty()) )
471             m_aAutoIncrement.reset( new TStringPair(aAutoIncrement));
472         if ( aDelimiter.bUsed )
473             m_aDelimiter.reset( new TDelimiter( aDelimiter ) );
474 
475         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_DATASOURCE, true, true);
476 
477         exportConnectionData();
478         exportDriverSettings(aSettingsMap);
479         exportApplicationConnectionSettings(aSettingsMap);
480     }
481     catch( const Exception& )
482     {
483         DBG_UNHANDLED_EXCEPTION("dbaccess");
484     }
485 }
486 
487 void ODBExport::exportApplicationConnectionSettings(const TSettingsMap& _aSettings)
488 {
489     const ::xmloff::token::XMLTokenEnum pSettings[] = {
490         XML_IS_TABLE_NAME_LENGTH_LIMITED
491         ,XML_ENABLE_SQL92_CHECK
492         ,XML_APPEND_TABLE_ALIAS_NAME
493         ,XML_IGNORE_DRIVER_PRIVILEGES
494         ,XML_BOOLEAN_COMPARISON_MODE
495         ,XML_USE_CATALOG
496         ,XML_MAX_ROW_COUNT
497         ,XML_SUPPRESS_VERSION_COLUMNS
498     };
499     for (::xmloff::token::XMLTokenEnum i : pSettings)
500     {
501         TSettingsMap::const_iterator aFind = _aSettings.find(i);
502         if ( aFind != _aSettings.end() )
503             AddAttribute(XML_NAMESPACE_DB, aFind->first,aFind->second);
504     }
505     SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_APPLICATION_CONNECTION_SETTINGS, true, true);
506 
507     Reference<XPropertySet> xProp(getDataSource());
508     Sequence< OUString> aValue;
509     xProp->getPropertyValue(PROPERTY_TABLEFILTER) >>= aValue;
510     if ( aValue.getLength() )
511     {
512         SvXMLElementExport aElem2(*this,XML_NAMESPACE_DB, XML_TABLE_FILTER, true, true);
513         exportSequence(aValue,XML_TABLE_INCLUDE_FILTER,XML_TABLE_FILTER_PATTERN);
514     }
515 
516     xProp->getPropertyValue(PROPERTY_TABLETYPEFILTER) >>= aValue;
517     if ( aValue.getLength() )
518         exportSequence(aValue,XML_TABLE_TYPE_FILTER,XML_TABLE_TYPE);
519 
520     exportDataSourceSettings();
521 }
522 
523 void ODBExport::exportDriverSettings(const TSettingsMap& _aSettings)
524 {
525     const ::xmloff::token::XMLTokenEnum pSettings[] = {
526         XML_SHOW_DELETED
527         ,XML_SYSTEM_DRIVER_SETTINGS
528         ,XML_BASE_DN
529         ,XML_IS_FIRST_ROW_HEADER_LINE
530         ,XML_PARAMETER_NAME_SUBSTITUTION
531     };
532     for (::xmloff::token::XMLTokenEnum nSetting : pSettings)
533     {
534         TSettingsMap::const_iterator aFind = _aSettings.find(nSetting);
535         if ( aFind != _aSettings.end() )
536             AddAttribute(XML_NAMESPACE_DB, aFind->first,aFind->second);
537     }
538     SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_DRIVER_SETTINGS, true, true);
539     exportAutoIncrement();
540     exportDelimiter();
541     exportCharSet();
542 }
543 
544 void ODBExport::exportConnectionData()
545 {
546     SvXMLElementExport aConnData(*this,XML_NAMESPACE_DB, XML_CONNECTION_DATA, true, true);
547 
548     {
549         OUString sValue;
550         Reference<XPropertySet> xProp(getDataSource());
551         xProp->getPropertyValue(PROPERTY_URL) >>= sValue;
552         if ( m_aTypeCollection.isFileSystemBased(sValue) )
553         {
554             SvXMLElementExport aDatabaseDescription(*this,XML_NAMESPACE_DB, XML_DATABASE_DESCRIPTION, true, true);
555             {
556                 SvtPathOptions aPathOptions;
557                 const OUString sOrigUrl = m_aTypeCollection.cutPrefix(sValue);
558                 OUString sFileName = aPathOptions.SubstituteVariable(sOrigUrl);
559                 if ( sOrigUrl == sFileName )
560                 {
561                     ::svt::OFileNotation aTransformer( sFileName );
562                     OUStringBuffer sURL( aTransformer.get( ::svt::OFileNotation::N_URL ) );
563                     if (sURL.isEmpty() || sURL[sURL.getLength() - 1] != '/')
564                         sURL.append('/');
565 
566                     AddAttribute(XML_NAMESPACE_XLINK,XML_HREF,GetRelativeReference(sURL.makeStringAndClear()));
567                 }
568                 else
569                     AddAttribute(XML_NAMESPACE_XLINK,XML_HREF,sOrigUrl);
570                 AddAttribute(XML_NAMESPACE_DB,XML_MEDIA_TYPE,m_aTypeCollection.getMediaType(sValue));
571                 const ::dbaccess::DATASOURCE_TYPE eType = m_aTypeCollection.determineType(sValue);
572                 try
573                 {
574                     OUString sExtension;
575                     if ( eType == dbaccess::DST_MSACCESS )
576                         sExtension = "mdb";
577                     else
578                     {
579                         Reference< XPropertySet > xDataSourceSettings;
580                         OSL_VERIFY( xProp->getPropertyValue( PROPERTY_SETTINGS ) >>= xDataSourceSettings );
581                         xDataSourceSettings->getPropertyValue( INFO_TEXTFILEEXTENSION ) >>= sExtension;
582                     }
583                     if ( !sExtension.isEmpty() )
584                         AddAttribute(XML_NAMESPACE_DB,XML_EXTENSION,sExtension);
585                 }
586                 catch(const Exception&)
587                 {
588                 }
589                 SvXMLElementExport aFileBasedDB(*this,XML_NAMESPACE_DB, XML_FILE_BASED_DATABASE, true, true);
590             }
591         }
592         else
593         {
594             OUString sDatabaseName,sHostName;
595             sal_Int32 nPort = -1;
596             m_aTypeCollection.extractHostNamePort(sValue,sDatabaseName,sHostName,nPort);
597             if ( sHostName.getLength() )
598             {
599                 SvXMLElementExport aDatabaseDescription(*this,XML_NAMESPACE_DB, XML_DATABASE_DESCRIPTION, true, true);
600                 {
601                     OUString sType = comphelper::string::stripEnd(m_aTypeCollection.getPrefix(sValue), ':');
602                     AddAttribute(XML_NAMESPACE_DB,XML_TYPE,sType);
603                     AddAttribute(XML_NAMESPACE_DB,XML_HOSTNAME,sHostName);
604                     if ( nPort != -1 )
605                         AddAttribute(XML_NAMESPACE_DB,XML_PORT,OUString::number(nPort));
606                     if ( sDatabaseName.getLength() )
607                         AddAttribute(XML_NAMESPACE_DB,XML_DATABASE_NAME,sDatabaseName);
608 
609                     try
610                     {
611                         Reference< XPropertySet > xDataSourceSettings( xProp->getPropertyValue( PROPERTY_SETTINGS ), UNO_QUERY_THROW );
612                         Reference< XPropertySetInfo > xSettingsInfo( xDataSourceSettings->getPropertySetInfo(), UNO_SET_THROW );
613 
614 
615                         const OUString sPropertyName = "LocalSocket";
616                         if ( xSettingsInfo->hasPropertyByName( sPropertyName ) )
617                         {
618                             OUString sPropertyValue;
619                             if ( ( xDataSourceSettings->getPropertyValue( sPropertyName ) >>= sPropertyValue ) && !sPropertyValue.isEmpty() )
620                                 AddAttribute( XML_NAMESPACE_DB, XML_LOCAL_SOCKET, sPropertyValue );
621                         }
622                     }
623                     catch( const Exception& )
624                     {
625                         DBG_UNHANDLED_EXCEPTION("dbaccess");
626                     }
627 
628                     SvXMLElementExport aServerDB(*this,XML_NAMESPACE_DB, XML_SERVER_DATABASE, true, true);
629                 }
630             }
631             else
632             {
633                 AddAttribute(XML_NAMESPACE_XLINK, XML_HREF,sValue);
634                 AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
635                 SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_CONNECTION_RESOURCE, true, true);
636             }
637         }
638 
639     }
640 
641     exportLogin();
642 }
643 
644 template< typename T > void ODBExport::exportDataSourceSettingsSequence(
645     std::vector< TypedPropertyValue >::iterator const & in)
646 {
647     css::uno::Sequence<T> anySeq;
648     bool bSuccess = in->Value >>= anySeq;
649     assert(bSuccess); (void)bSuccess;
650     for (T const & i : anySeq )
651     {
652         SvXMLElementExport aDataValue(*this,XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING_VALUE, true, false);
653         // (no whitespace inside the tag)
654         Characters(implConvertAny(css::uno::Any(i)));
655     }
656 }
657 
658 void ODBExport::exportDataSourceSettings()
659 {
660     if ( m_aDataSourceSettings.empty() )
661         return;
662 
663     SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTINGS, true, true);
664     std::vector< TypedPropertyValue >::iterator aIter = m_aDataSourceSettings.begin();
665     std::vector< TypedPropertyValue >::const_iterator aEnd = m_aDataSourceSettings.end();
666     for ( ; aIter != aEnd; ++aIter )
667     {
668         const bool bIsSequence = TypeClass_SEQUENCE == aIter->Type.getTypeClass();
669 
670         Type aSimpleType(bIsSequence ? comphelper::getSequenceElementType(aIter->Value.getValueType()) : aIter->Type);
671 
672         AddAttribute( XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING_IS_LIST,bIsSequence ? XML_TRUE : XML_FALSE );
673         AddAttribute( XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING_NAME, aIter->Name );
674 
675         OUString sTypeName = lcl_implGetPropertyXMLType( aSimpleType );
676         if ( bIsSequence && aSimpleType.getTypeClass() == TypeClass_ANY )
677         {
678             Sequence<Any> aSeq;
679             aIter->Value >>= aSeq;
680             if ( aSeq.getLength() )
681                 sTypeName = lcl_implGetPropertyXMLType(aSeq[0].getValueType());
682         }
683 
684         AddAttribute( XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING_TYPE, sTypeName );
685 
686         SvXMLElementExport aDataSourceSetting( *this, XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING, true, true );
687 
688         if ( !bIsSequence )
689         {
690             SvXMLElementExport aDataValue( *this, XML_NAMESPACE_DB, XML_DATA_SOURCE_SETTING_VALUE, true, false );
691             // (no whitespace inside the tag)
692             Characters( implConvertAny( aIter->Value ) );
693         }
694         else
695         {
696             // the not-that-simple case, we need to iterate through the sequence elements
697             switch (aSimpleType.getTypeClass())
698             {
699                 case TypeClass_STRING:
700                     exportDataSourceSettingsSequence< OUString >(
701                         aIter );
702                     break;
703                 case TypeClass_DOUBLE:
704                     exportDataSourceSettingsSequence< double >( aIter );
705                     break;
706                 case TypeClass_BOOLEAN:
707                     exportDataSourceSettingsSequence< sal_Bool >( aIter );
708                     break;
709                 case TypeClass_BYTE:
710                     exportDataSourceSettingsSequence< sal_Int8 >( aIter );
711                     break;
712                 case TypeClass_SHORT:
713                     exportDataSourceSettingsSequence< sal_Int16 >( aIter );
714                     break;
715                 case TypeClass_LONG:
716                     exportDataSourceSettingsSequence< sal_Int32 >( aIter );
717                     break;
718                 case TypeClass_ANY:
719                     exportDataSourceSettingsSequence< Any >( aIter );
720                     break;
721                 default:
722                     OSL_FAIL("unsupported sequence type !");
723                     break;
724             }
725         }
726     }
727 }
728 
729 void ODBExport::exportCharSet()
730 {
731     if ( !m_sCharSet.isEmpty() )
732     {
733         AddAttribute(XML_NAMESPACE_DB, XML_ENCODING,m_sCharSet);
734 
735         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_FONT_CHARSET, true, true);
736     }
737 }
738 
739 void ODBExport::exportDelimiter()
740 {
741     if ( m_aDelimiter.get() && m_aDelimiter->bUsed )
742     {
743         AddAttribute(XML_NAMESPACE_DB, XML_FIELD,m_aDelimiter->sField);
744         AddAttribute(XML_NAMESPACE_DB, XML_STRING,m_aDelimiter->sText);
745         AddAttribute(XML_NAMESPACE_DB, XML_DECIMAL,m_aDelimiter->sDecimal);
746         AddAttribute(XML_NAMESPACE_DB, XML_THOUSAND,m_aDelimiter->sThousand);
747         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_DELIMITER, true, true);
748     }
749 }
750 
751 void ODBExport::exportAutoIncrement()
752 {
753     if (m_aAutoIncrement)
754     {
755         AddAttribute(XML_NAMESPACE_DB, XML_ADDITIONAL_COLUMN_STATEMENT,m_aAutoIncrement->second);
756         AddAttribute(XML_NAMESPACE_DB, XML_ROW_RETRIEVING_STATEMENT,m_aAutoIncrement->first);
757         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_AUTO_INCREMENT, true, true);
758     }
759 }
760 
761 void ODBExport::exportSequence(const Sequence< OUString>& _aValue
762                             ,::xmloff::token::XMLTokenEnum _eTokenFilter
763                             ,::xmloff::token::XMLTokenEnum _eTokenType)
764 {
765     Reference<XPropertySet> xProp(getDataSource());
766     if ( _aValue.getLength() )
767     {
768         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, _eTokenFilter, true, true);
769 
770         const OUString* pIter = _aValue.getConstArray();
771         const OUString* pEnd   = pIter + _aValue.getLength();
772         for(;pIter != pEnd;++pIter)
773         {
774             SvXMLElementExport aDataSource(*this,XML_NAMESPACE_DB, _eTokenType, true, false);
775             Characters(*pIter);
776         }
777     }
778 }
779 
780 void ODBExport::exportLogin()
781 {
782     Reference<XPropertySet> xProp(getDataSource());
783     OUString sValue;
784     xProp->getPropertyValue(PROPERTY_USER) >>= sValue;
785     bool bAddLogin = !sValue.isEmpty();
786     if ( bAddLogin )
787         AddAttribute(XML_NAMESPACE_DB, XML_USER_NAME,sValue);
788     bool bValue = false;
789     if ( xProp->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED) >>= bValue )
790     {
791         bAddLogin = true;
792         AddAttribute(XML_NAMESPACE_DB, XML_IS_PASSWORD_REQUIRED,bValue ? XML_TRUE : XML_FALSE);
793     }
794     if ( bAddLogin )
795         SvXMLElementExport aElem(*this,XML_NAMESPACE_DB, XML_LOGIN, true, true);
796 }
797 
798 void ODBExport::exportCollection(const Reference< XNameAccess >& _xCollection
799                                 ,enum ::xmloff::token::XMLTokenEnum _eComponents
800                                 ,enum ::xmloff::token::XMLTokenEnum _eSubComponents
801                                 ,bool _bExportContext
802                                 ,const ::comphelper::mem_fun1_t<ODBExport,XPropertySet* >& _aMemFunc
803                                 )
804 {
805     if ( _xCollection.is() )
806     {
807         std::unique_ptr<SvXMLElementExport> pComponents;
808         if ( _bExportContext )
809             pComponents.reset( new SvXMLElementExport(*this,XML_NAMESPACE_DB, _eComponents, true, true));
810         Sequence< OUString> aSeq = _xCollection->getElementNames();
811         const OUString* pIter = aSeq.getConstArray();
812         const OUString* pEnd   = pIter + aSeq.getLength();
813         for(;pIter != pEnd;++pIter)
814         {
815             Reference<XPropertySet> xProp(_xCollection->getByName(*pIter),UNO_QUERY);
816             if ( _bExportContext && XML_TABLE_REPRESENTATIONS != _eComponents )
817                 AddAttribute(XML_NAMESPACE_DB, XML_NAME,*pIter);
818             Reference< XNameAccess > xSub(xProp,UNO_QUERY);
819             if ( xSub.is() )
820             {
821                 exportCollection(xSub,_eSubComponents,_eSubComponents,_bExportContext,_aMemFunc);
822             }
823             else if ( xProp.is() )
824                 _aMemFunc(this,xProp.get());
825         }
826     }
827 }
828 
829 void ODBExport::exportComponent(XPropertySet* _xProp)
830 {
831     OUString sValue;
832     _xProp->getPropertyValue(PROPERTY_PERSISTENT_NAME) >>= sValue;
833     bool bIsForm = true;
834     _xProp->getPropertyValue("IsForm") >>= bIsForm;
835     if ( bIsForm )
836         sValue = "forms/" + sValue;
837     else
838         sValue = "reports/" + sValue;
839 
840     AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sValue);
841     AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
842     bool bAsTemplate = false;
843     _xProp->getPropertyValue(PROPERTY_AS_TEMPLATE) >>= bAsTemplate;
844     AddAttribute(XML_NAMESPACE_DB, XML_AS_TEMPLATE,bAsTemplate ? XML_TRUE : XML_FALSE);
845     SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, XML_COMPONENT, true, true);
846 }
847 
848 void ODBExport::exportQuery(XPropertySet* _xProp)
849 {
850     AddAttribute(XML_NAMESPACE_DB, XML_COMMAND,getString(_xProp->getPropertyValue(PROPERTY_COMMAND)));
851 
852     if ( getBOOL(_xProp->getPropertyValue(PROPERTY_APPLYFILTER)) )
853         AddAttribute(XML_NAMESPACE_DB, XML_APPLY_FILTER,XML_TRUE);
854 
855     if ( _xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_APPLYORDER)
856         && getBOOL(_xProp->getPropertyValue(PROPERTY_APPLYORDER)) )
857         AddAttribute(XML_NAMESPACE_DB, XML_APPLY_ORDER,XML_TRUE);
858 
859     if ( ! getBOOL(_xProp->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) )
860         AddAttribute(XML_NAMESPACE_DB, XML_ESCAPE_PROCESSING,XML_FALSE);
861 
862     exportStyleName(_xProp,GetAttrList());
863 
864     SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, XML_QUERY, true, true);
865     Reference<XColumnsSupplier> xCol(_xProp,UNO_QUERY);
866     exportColumns(xCol);
867     exportFilter(_xProp,PROPERTY_FILTER,XML_FILTER_STATEMENT);
868     exportFilter(_xProp,PROPERTY_ORDER,XML_ORDER_STATEMENT);
869     exportTableName(_xProp,true);
870 }
871 
872 void ODBExport::exportTable(XPropertySet* _xProp)
873 {
874     exportTableName(_xProp,false);
875 
876     if ( _xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_DESCRIPTION) )
877         AddAttribute(XML_NAMESPACE_DB, XML_DESCRIPTION,getString(_xProp->getPropertyValue(PROPERTY_DESCRIPTION)));
878 
879     if ( getBOOL(_xProp->getPropertyValue(PROPERTY_APPLYFILTER)) )
880         AddAttribute(XML_NAMESPACE_DB, XML_APPLY_FILTER,XML_TRUE);
881 
882     if ( _xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_APPLYORDER)
883         && getBOOL(_xProp->getPropertyValue(PROPERTY_APPLYORDER)) )
884         AddAttribute(XML_NAMESPACE_DB, XML_APPLY_ORDER,XML_TRUE);
885 
886     exportStyleName(_xProp,GetAttrList());
887 
888     SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, XML_TABLE_REPRESENTATION, true, true);
889     Reference<XColumnsSupplier> xCol(_xProp,UNO_QUERY);
890     exportColumns(xCol);
891     exportFilter(_xProp,PROPERTY_FILTER,XML_FILTER_STATEMENT);
892     exportFilter(_xProp,PROPERTY_ORDER,XML_ORDER_STATEMENT);
893 }
894 
895 void ODBExport::exportStyleName(XPropertySet* _xProp,SvXMLAttributeList& _rAtt)
896 {
897     Reference<XPropertySet> xFind(_xProp);
898     exportStyleName(XML_STYLE_NAME,xFind,_rAtt,m_aAutoStyleNames);
899     exportStyleName(XML_DEFAULT_CELL_STYLE_NAME,xFind,_rAtt,m_aCellAutoStyleNames);
900     exportStyleName(XML_DEFAULT_ROW_STYLE_NAME,xFind,_rAtt,m_aRowAutoStyleNames);
901 }
902 
903 void ODBExport::exportStyleName(const ::xmloff::token::XMLTokenEnum _eToken,const uno::Reference<beans::XPropertySet>& _xProp,SvXMLAttributeList& _rAtt,TPropertyStyleMap& _rMap)
904 {
905     TPropertyStyleMap::const_iterator aFind = _rMap.find(_xProp);
906     if ( aFind != _rMap.end() )
907     {
908         _rAtt.AddAttribute( GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DB, GetXMLToken(_eToken) ),
909                             aFind->second );
910         _rMap.erase(aFind);
911     }
912 }
913 
914 void ODBExport::exportTableName(XPropertySet* _xProp,bool _bUpdate)
915 {
916     OUString sValue;
917     _xProp->getPropertyValue(_bUpdate ? OUString(PROPERTY_UPDATE_TABLENAME) : OUString(PROPERTY_NAME)) >>= sValue;
918     if ( !sValue.isEmpty() )
919     {
920         AddAttribute(XML_NAMESPACE_DB, XML_NAME,sValue);
921         _xProp->getPropertyValue(_bUpdate ? OUString(PROPERTY_UPDATE_SCHEMANAME) : OUString(PROPERTY_SCHEMANAME)) >>= sValue;
922         if ( !sValue.isEmpty() )
923             AddAttribute(XML_NAMESPACE_DB, XML_SCHEMA_NAME,sValue);
924         _xProp->getPropertyValue(_bUpdate ? OUString(PROPERTY_UPDATE_CATALOGNAME) : OUString(PROPERTY_CATALOGNAME)) >>= sValue;
925         if ( !sValue.isEmpty() )
926             AddAttribute(XML_NAMESPACE_DB, XML_CATALOG_NAME,sValue);
927 
928         if ( _bUpdate )
929         {
930             SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, XML_UPDATE_TABLE, true, true);
931         }
932     }
933 }
934 
935 void ODBExport::exportFilter(XPropertySet* _xProp
936                              ,const OUString& _sProp
937                              ,enum ::xmloff::token::XMLTokenEnum _eStatementType)
938 {
939     OSL_PRECOND(!GetAttrList().getLength(),"Invalid attribute length!");
940     OUString sCommand;
941     _xProp->getPropertyValue(_sProp) >>= sCommand;
942     if ( !sCommand.isEmpty() )
943     {
944         AddAttribute(XML_NAMESPACE_DB, XML_COMMAND,sCommand);
945         SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, _eStatementType, true, true);
946     }
947     SAL_WARN_IF(GetAttrList().getLength(), "dbaccess", "Invalid attribute length!");
948 }
949 
950 void ODBExport::exportColumns(const Reference<XColumnsSupplier>& _xColSup)
951 {
952     OSL_PRECOND( _xColSup.is(), "ODBExport::exportColumns: invalid columns supplier!" );
953     if ( !_xColSup.is() )
954         return;
955 
956     try
957     {
958         Reference<XNameAccess> xNameAccess( _xColSup->getColumns(), UNO_SET_THROW );
959         if ( !xNameAccess->hasElements() )
960         {
961             Reference< XPropertySet > xComponent(_xColSup,UNO_QUERY);
962             TTableColumnMap::const_iterator aFind = m_aTableDummyColumns.find(xComponent);
963             if ( aFind != m_aTableDummyColumns.end() )
964             {
965                 SvXMLElementExport aColumns(*this,XML_NAMESPACE_DB, XML_COLUMNS, true, true);
966                 SvXMLAttributeList* pAtt = new SvXMLAttributeList;
967                 Reference<XAttributeList> xAtt = pAtt;
968                 exportStyleName(aFind->second.get(),*pAtt);
969                 AddAttributeList(xAtt);
970                 SvXMLElementExport aColumn(*this,XML_NAMESPACE_DB, XML_COLUMN, true, true);
971 
972             }
973             return;
974         }
975 
976         SvXMLElementExport aColumns(*this,XML_NAMESPACE_DB, XML_COLUMNS, true, true);
977         Sequence< OUString> aSeq = xNameAccess->getElementNames();
978         const OUString* pIter = aSeq.getConstArray();
979         const OUString* pEnd   = pIter + aSeq.getLength();
980         for( ; pIter != pEnd ; ++pIter)
981         {
982             Reference<XPropertySet> xProp(xNameAccess->getByName(*pIter),UNO_QUERY);
983             if ( xProp.is() )
984             {
985                 SvXMLAttributeList* pAtt = new SvXMLAttributeList;
986                 Reference<XAttributeList> xAtt = pAtt;
987                 exportStyleName(xProp.get(),*pAtt);
988 
989                 bool bHidden = getBOOL(xProp->getPropertyValue(PROPERTY_HIDDEN));
990 
991                 OUString sValue;
992                 xProp->getPropertyValue(PROPERTY_HELPTEXT) >>= sValue;
993                 Any aColumnDefault;
994                 aColumnDefault = xProp->getPropertyValue(PROPERTY_CONTROLDEFAULT);
995 
996                 if ( bHidden || !sValue.isEmpty() || aColumnDefault.hasValue() || pAtt->getLength() )
997                 {
998                     AddAttribute(XML_NAMESPACE_DB, XML_NAME,*pIter);
999                     if ( bHidden )
1000                         AddAttribute(XML_NAMESPACE_DB, XML_VISIBLE,XML_FALSE);
1001 
1002                     if ( !sValue.isEmpty() )
1003                         AddAttribute(XML_NAMESPACE_DB, XML_HELP_MESSAGE,sValue);
1004 
1005                     if ( aColumnDefault.hasValue() )
1006                     {
1007                         OUStringBuffer sColumnDefaultString,sType;
1008                         ::sax::Converter::convertAny(
1009                             sColumnDefaultString, sType, aColumnDefault );
1010                         AddAttribute(XML_NAMESPACE_DB, XML_TYPE_NAME,sType.makeStringAndClear());
1011                         AddAttribute(XML_NAMESPACE_DB, XML_DEFAULT_VALUE,sColumnDefaultString.makeStringAndClear());
1012                     }
1013 
1014                     if ( pAtt->getLength() )
1015                         AddAttributeList(xAtt);
1016                 }
1017 
1018                 if ( GetAttrList().getLength() )
1019                 {
1020                     SvXMLElementExport aComponents(*this,XML_NAMESPACE_DB, XML_COLUMN, true, true);
1021                 }
1022             }
1023         }
1024     }
1025     catch( const Exception& )
1026     {
1027         DBG_UNHANDLED_EXCEPTION("dbaccess");
1028     }
1029 }
1030 
1031 void ODBExport::exportForms()
1032 {
1033     Any aValue;
1034     OUString sService;
1035     dbtools::getDataSourceSetting(getDataSource(),"Forms",aValue);
1036     aValue >>= sService;
1037     if ( sService.isEmpty() )
1038     {
1039         Reference<XFormDocumentsSupplier> xSup(GetModel(),UNO_QUERY);
1040         if ( xSup.is() )
1041         {
1042             Reference< XNameAccess > xCollection = xSup->getFormDocuments();
1043             if ( xCollection.is() && xCollection->hasElements() )
1044             {
1045                 ::comphelper::mem_fun1_t<ODBExport,XPropertySet* > aMemFunc(&ODBExport::exportComponent);
1046                 exportCollection(xCollection,XML_FORMS,XML_COMPONENT_COLLECTION,true,aMemFunc);
1047             }
1048         }
1049     }
1050 }
1051 
1052 void ODBExport::exportReports()
1053 {
1054     Any aValue;
1055     OUString sService;
1056     dbtools::getDataSourceSetting(getDataSource(),"Reports",aValue);
1057     aValue >>= sService;
1058     if ( sService.isEmpty() )
1059     {
1060         Reference<XReportDocumentsSupplier> xSup(GetModel(),UNO_QUERY);
1061         if ( xSup.is() )
1062         {
1063             Reference< XNameAccess > xCollection = xSup->getReportDocuments();
1064             if ( xCollection.is() && xCollection->hasElements() )
1065             {
1066                 ::comphelper::mem_fun1_t<ODBExport,XPropertySet* > aMemFunc(&ODBExport::exportComponent);
1067                 exportCollection(xCollection,XML_REPORTS,XML_COMPONENT_COLLECTION,true,aMemFunc);
1068             }
1069         }
1070     }
1071 }
1072 
1073 void ODBExport::exportQueries(bool _bExportContext)
1074 {
1075     Any aValue;
1076     OUString sService;
1077     dbtools::getDataSourceSetting(getDataSource(),"CommandDefinitions",aValue);
1078     aValue >>= sService;
1079     if ( sService.isEmpty() )
1080     {
1081         Reference<XQueryDefinitionsSupplier> xSup(getDataSource(),UNO_QUERY);
1082         if ( xSup.is() )
1083         {
1084             Reference< XNameAccess > xCollection = xSup->getQueryDefinitions();
1085             if ( xCollection.is() && xCollection->hasElements() )
1086             {
1087                 std::unique_ptr< ::comphelper::mem_fun1_t<ODBExport,XPropertySet* > > pMemFunc;
1088                 if ( _bExportContext )
1089                     pMemFunc.reset( new ::comphelper::mem_fun1_t<ODBExport,XPropertySet* >(&ODBExport::exportQuery) );
1090                 else
1091                     pMemFunc.reset( new ::comphelper::mem_fun1_t<ODBExport,XPropertySet* >(&ODBExport::exportAutoStyle) );
1092 
1093                 exportCollection(xCollection,XML_QUERIES,XML_QUERY_COLLECTION,_bExportContext,*pMemFunc);
1094             }
1095         }
1096     }
1097 }
1098 
1099 void ODBExport::exportTables(bool _bExportContext)
1100 {
1101     Reference<XTablesSupplier> xSup(getDataSource(),UNO_QUERY);
1102     if ( xSup.is() )
1103     {
1104         Reference< XNameAccess > xCollection = xSup->getTables();
1105         if ( xCollection.is() && xCollection->hasElements() )
1106         {
1107             std::unique_ptr< ::comphelper::mem_fun1_t<ODBExport,XPropertySet* > > pMemFunc;
1108             if ( _bExportContext )
1109                 pMemFunc.reset( new ::comphelper::mem_fun1_t<ODBExport,XPropertySet* >(&ODBExport::exportTable) );
1110             else
1111                 pMemFunc.reset( new ::comphelper::mem_fun1_t<ODBExport,XPropertySet* >(&ODBExport::exportAutoStyle) );
1112             exportCollection(xCollection,XML_TABLE_REPRESENTATIONS,XML_TOKEN_INVALID,_bExportContext,*pMemFunc);
1113         }
1114     }
1115 }
1116 
1117 void ODBExport::exportAutoStyle(XPropertySet* _xProp)
1118 {
1119     typedef std::pair<TPropertyStyleMap*,sal_uInt16> TEnumMapperPair;
1120     typedef std::pair< rtl::Reference < SvXMLExportPropertyMapper> , TEnumMapperPair> TExportPropMapperPair;
1121     Reference<XColumnsSupplier> xSup(_xProp,UNO_QUERY);
1122     if ( xSup.is() )
1123     {
1124         const TExportPropMapperPair pExportHelper[] = {
1125              TExportPropMapperPair(m_xExportHelper,TEnumMapperPair(&m_aAutoStyleNames,XML_STYLE_FAMILY_TABLE_TABLE ))
1126             // ,TExportPropMapperPair(m_xCellExportHelper,TEnumMapperPair(&m_aCellAutoStyleNames,XML_STYLE_FAMILY_TABLE_CELL))
1127             ,TExportPropMapperPair(m_xRowExportHelper,TEnumMapperPair(&m_aRowAutoStyleNames,XML_STYLE_FAMILY_TABLE_ROW))
1128         };
1129 
1130         std::vector< XMLPropertyState > aPropertyStates;
1131         for (const auto & i : pExportHelper)
1132         {
1133             aPropertyStates = i.first->Filter(_xProp);
1134             if ( !aPropertyStates.empty() )
1135                 i.second.first->emplace( _xProp,GetAutoStylePool()->Add( i.second.second, aPropertyStates ) );
1136         }
1137 
1138         Reference< XNameAccess > xCollection;
1139         try
1140         {
1141             xCollection.set( xSup->getColumns(), UNO_SET_THROW );
1142             awt::FontDescriptor aFont;
1143             _xProp->getPropertyValue(PROPERTY_FONT) >>= aFont;
1144             GetFontAutoStylePool()->Add(aFont.Name,aFont.StyleName,static_cast<FontFamily>(aFont.Family),
1145                 static_cast<FontPitch>(aFont.Pitch),aFont.CharSet );
1146 
1147             m_aCurrentPropertyStates = m_xCellExportHelper->Filter(_xProp);
1148             if ( !m_aCurrentPropertyStates.empty() && !xCollection->hasElements() )
1149             {
1150                 Reference< XDataDescriptorFactory> xFac(xCollection,UNO_QUERY);
1151                 if ( xFac.is() )
1152                 {
1153                     Reference< XPropertySet> xColumn = xFac->createDataDescriptor();
1154                     m_aTableDummyColumns.emplace( Reference< XPropertySet>(_xProp),xColumn );
1155                     exportAutoStyle(xColumn.get());
1156                 }
1157             }
1158             else
1159             {
1160                 ::comphelper::mem_fun1_t<ODBExport,XPropertySet* > aMemFunc(&ODBExport::exportAutoStyle);
1161                 exportCollection(xCollection,XML_TOKEN_INVALID,XML_TOKEN_INVALID,false,aMemFunc);
1162             }
1163         }
1164         catch(const Exception&)
1165         {
1166             DBG_UNHANDLED_EXCEPTION("dbaccess");
1167         }
1168         m_aCurrentPropertyStates.clear();
1169     }
1170     else
1171     { // here I know I have a column
1172         const TExportPropMapperPair pExportHelper[] = {
1173              TExportPropMapperPair(m_xColumnExportHelper,TEnumMapperPair(&m_aAutoStyleNames,XML_STYLE_FAMILY_TABLE_COLUMN ))
1174             ,TExportPropMapperPair(m_xCellExportHelper,TEnumMapperPair(&m_aCellAutoStyleNames,XML_STYLE_FAMILY_TABLE_CELL))
1175         };
1176         for (const auto & i : pExportHelper)
1177         {
1178             std::vector< XMLPropertyState > aPropStates = i.first->Filter( _xProp );
1179             if ( !aPropStates.empty() )
1180             {
1181                 const rtl::Reference < XMLPropertySetMapper >& pStyle = i.first->getPropertySetMapper();
1182                 for (auto & propState : aPropStates)
1183                 {
1184                     if ( propState.mnIndex != -1 )
1185                     {
1186                         switch ( pStyle->GetEntryContextId(propState.mnIndex) )
1187                         {
1188                             case CTF_DB_NUMBERFORMAT:
1189                                 {
1190                                     sal_Int32 nNumberFormat = -1;
1191                                     if ( propState.maValue >>= nNumberFormat )
1192                                         addDataStyle(nNumberFormat);
1193                                 }
1194                                 break;
1195                             case CTF_DB_COLUMN_TEXT_ALIGN:
1196                                 if ( !propState.maValue.hasValue() )
1197                                     propState.maValue <<= css::awt::TextAlign::LEFT;
1198                                 break;
1199                         }
1200                     }
1201                 }
1202 
1203             }
1204             if ( XML_STYLE_FAMILY_TABLE_CELL == i.second.second )
1205                 std::copy( m_aCurrentPropertyStates.begin(), m_aCurrentPropertyStates.end(), std::back_inserter( aPropStates ));
1206             if ( !aPropStates.empty() )
1207                 i.second.first->emplace( _xProp,GetAutoStylePool()->Add( i.second.second, aPropStates ) );
1208         }
1209     }
1210 }
1211 
1212 void ODBExport::ExportContent_()
1213 {
1214     exportDataSource();
1215     exportForms();
1216     exportReports();
1217     exportQueries(true);
1218     exportTables(true);
1219 }
1220 
1221 void ODBExport::ExportMasterStyles_()
1222 {
1223     GetPageExport()->exportMasterStyles( true );
1224 }
1225 
1226 void ODBExport::ExportAutoStyles_()
1227 {
1228     // there are no styles that require their own autostyles
1229     if ( getExportFlags() & SvXMLExportFlags::CONTENT )
1230     {
1231         collectComponentStyles();
1232         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE);
1233         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN);
1234         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL);
1235         GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW);
1236         exportDataStyles();
1237     }
1238 }
1239 
1240 void ODBExport::GetViewSettings(Sequence<PropertyValue>& aProps)
1241 {
1242     Reference<XQueryDefinitionsSupplier> xSup(getDataSource(),UNO_QUERY);
1243     if ( xSup.is() )
1244     {
1245         Reference< XNameAccess > xCollection = xSup->getQueryDefinitions();
1246         if ( xCollection.is() && xCollection->hasElements() )
1247         {
1248             try
1249             {
1250                 sal_Int32 nLength = aProps.getLength();
1251                 aProps.realloc(nLength + 1);
1252                 aProps[nLength].Name = "Queries";
1253                 Sequence< OUString> aSeq = xCollection->getElementNames();
1254                 const OUString* pIter = aSeq.getConstArray();
1255                 const OUString* pEnd   = pIter + aSeq.getLength();
1256 
1257                 Sequence<PropertyValue> aQueries(aSeq.getLength());
1258                 for(sal_Int32 i = 0;pIter != pEnd;++pIter,++i)
1259                 {
1260                     Reference<XPropertySet> xProp(xCollection->getByName(*pIter),UNO_QUERY);
1261                     if ( xProp.is() )
1262                     {
1263                         aQueries[i].Name = *pIter;
1264                         aQueries[i].Value = xProp->getPropertyValue(PROPERTY_LAYOUTINFORMATION);
1265                     }
1266                 }
1267                 aProps[nLength].Value <<= aQueries;
1268             }
1269             catch(const Exception&)
1270             {
1271                 OSL_FAIL("ODBExport::GetViewSettings: Exception caught!");
1272             }
1273         }
1274     }
1275 
1276 }
1277 
1278 void ODBExport::GetConfigurationSettings(Sequence<PropertyValue>& aProps)
1279 {
1280     Reference<XPropertySet> xProp(getDataSource());
1281     if ( xProp.is() )
1282     {
1283         sal_Int32 nLength = aProps.getLength();
1284         try
1285         {
1286             Any aValue = xProp->getPropertyValue(PROPERTY_LAYOUTINFORMATION);
1287             Sequence< PropertyValue > aPropValues;
1288             aValue >>= aPropValues;
1289             if ( aPropValues.getLength() )
1290             {
1291                 aProps.realloc(nLength + 1);
1292                 aProps[nLength].Name = "layout-settings";
1293                 aProps[nLength].Value = aValue;
1294             }
1295         }
1296         catch(const Exception&)
1297         {
1298             OSL_FAIL("Could not access layout information from the data source!");
1299         }
1300     }
1301 }
1302 
1303 OUString ODBExport::implConvertAny(const Any& _rValue)
1304 {
1305     OUStringBuffer aBuffer;
1306     switch (_rValue.getValueTypeClass())
1307     {
1308         case TypeClass_STRING:
1309         {   // extract the string
1310             OUString sCurrentValue;
1311             _rValue >>= sCurrentValue;
1312             aBuffer.append(sCurrentValue);
1313         }
1314         break;
1315         case TypeClass_DOUBLE:
1316             // let the unit converter format is as string
1317             ::sax::Converter::convertDouble(aBuffer, getDouble(_rValue));
1318             break;
1319         case TypeClass_BOOLEAN:
1320             aBuffer = getBOOL(_rValue) ? ::xmloff::token::GetXMLToken(XML_TRUE) : ::xmloff::token::GetXMLToken(XML_FALSE);
1321             break;
1322         case TypeClass_BYTE:
1323         case TypeClass_SHORT:
1324         case TypeClass_LONG:
1325             // let the unit converter format is as string
1326             aBuffer.append(getINT32(_rValue));
1327             break;
1328         default:
1329             OSL_FAIL("ODBExport::implConvertAny: Invalid type");
1330     }
1331 
1332     return aBuffer.makeStringAndClear();
1333 }
1334 
1335 rtl::Reference < XMLPropertySetMapper > const & ODBExport::GetTableStylesPropertySetMapper() const
1336 {
1337     if ( !m_xTableStylesPropertySetMapper.is() )
1338     {
1339         m_xTableStylesPropertySetMapper = OXMLHelper::GetTableStylesPropertySetMapper( true);
1340     }
1341     return m_xTableStylesPropertySetMapper;
1342 }
1343 
1344 rtl::Reference < XMLPropertySetMapper > const & ODBExport::GetCellStylesPropertySetMapper() const
1345 {
1346     if ( !m_xCellStylesPropertySetMapper.is() )
1347     {
1348         m_xCellStylesPropertySetMapper = OXMLHelper::GetCellStylesPropertySetMapper( true);
1349     }
1350     return m_xCellStylesPropertySetMapper;
1351 }
1352 
1353 rtl::Reference < XMLPropertySetMapper > const & ODBExport::GetColumnStylesPropertySetMapper() const
1354 {
1355     if ( !m_xColumnStylesPropertySetMapper.is() )
1356     {
1357         m_xColumnStylesPropertySetMapper = OXMLHelper::GetColumnStylesPropertySetMapper( true);
1358     }
1359     return m_xColumnStylesPropertySetMapper;
1360 }
1361 
1362 SvXMLAutoStylePoolP* ODBExport::CreateAutoStylePool()
1363 {
1364     return new OXMLAutoStylePoolP(*this);
1365 }
1366 
1367 void SAL_CALL ODBExport::setSourceDocument( const Reference< XComponent >& xDoc )
1368 {
1369     Reference<XOfficeDatabaseDocument> xOfficeDoc(xDoc,UNO_QUERY_THROW);
1370     m_xDataSource.set(xOfficeDoc->getDataSource(),UNO_QUERY_THROW);
1371     OSL_ENSURE(m_xDataSource.is(),"DataSource is NULL!");
1372     Reference< XNumberFormatsSupplier > xNum(m_xDataSource->getPropertyValue(PROPERTY_NUMBERFORMATSSUPPLIER),UNO_QUERY);
1373     SetNumberFormatsSupplier(xNum);
1374     SvXMLExport::setSourceDocument(xDoc);
1375 }
1376 
1377 void ODBExport::ExportFontDecls_()
1378 {
1379     GetFontAutoStylePool(); // make sure the pool is created
1380     collectComponentStyles();
1381     SvXMLExport::ExportFontDecls_();
1382 }
1383 
1384 void ODBExport::collectComponentStyles()
1385 {
1386     if ( m_bAllreadyFilled )
1387         return;
1388 
1389     m_bAllreadyFilled = true;
1390     exportQueries(false);
1391     exportTables(false);
1392 }
1393 
1394 }// dbaxml
1395 
1396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1397