LibreOffice Module xmloff (master) 1
xformsexport.cxx
Go to the documentation of this file.
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
22
23#include "XFormsModelExport.hxx"
24
25#include <xmloff/xmlexp.hxx>
26#include <xmloff/xmltoken.hxx>
29#include <DomExport.hxx>
30
32
35
36#include <tools/diagnose_ex.h>
37#include <sal/log.hxx>
38#include <com/sun/star/container/XIndexAccess.hpp>
39#include <com/sun/star/container/XNameAccess.hpp>
40#include <com/sun/star/document/NamedPropertyValues.hpp>
41#include <com/sun/star/frame/XModel.hpp>
42#include <com/sun/star/xml/dom/XDocument.hpp>
43#include <com/sun/star/form/binding/XBindableValue.hpp>
44#include <com/sun/star/form/binding/XListEntrySink.hpp>
45#include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
46#include <com/sun/star/xforms/XModel.hpp>
47#include <com/sun/star/xforms/XDataTypeRepository.hpp>
48#include <com/sun/star/xforms/XFormsSupplier.hpp>
49#include <com/sun/star/beans/PropertyValue.hpp>
50#include <com/sun/star/container/XEnumerationAccess.hpp>
51#include <com/sun/star/container/XEnumeration.hpp>
52#include <com/sun/star/container/XNameContainer.hpp>
53#include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
54#include <com/sun/star/xsd/DataTypeClass.hpp>
55#include <com/sun/star/util/Date.hpp>
56#include <com/sun/star/util/Time.hpp>
57#include <com/sun/star/util/DateTime.hpp>
58#include <com/sun/star/util/Duration.hpp>
59
60using namespace com::sun::star;
61using namespace com::sun::star::uno;
62using namespace xmloff::token;
63
65using com::sun::star::beans::XPropertySetInfo;
66using com::sun::star::container::XIndexAccess;
67using com::sun::star::container::XNameAccess;
68using com::sun::star::container::XNameContainer;
69using com::sun::star::container::XEnumerationAccess;
70using com::sun::star::container::XEnumeration;
71using com::sun::star::xml::dom::XDocument;
72using com::sun::star::form::binding::XBindableValue;
73using com::sun::star::form::binding::XListEntrySink;
74using com::sun::star::form::submission::XSubmissionSupplier;
75using com::sun::star::beans::PropertyValue;
76using com::sun::star::xforms::XDataTypeRepository;
77using com::sun::star::xforms::XFormsSupplier;
78using com::sun::star::util::Duration;
79
80void exportXForms( SvXMLExport& rExport )
81{
82 Reference<XFormsSupplier> xSupplier( rExport.GetModel(), UNO_QUERY );
83 if( !xSupplier.is() )
84 return;
85
86 Reference<XNameContainer> xForms = xSupplier->getXForms();
87 if( xForms.is() )
88 {
89 const Sequence<OUString> aNames = xForms->getElementNames();
90
91 for( const auto& rName : aNames )
92 {
93 Reference<XPropertySet> xModel( xForms->getByName( rName ),
94 UNO_QUERY );
95 exportXFormsModel( rExport, xModel );
96 }
97 }
98}
99
100
105
106
107typedef OUString (*convert_t)( const Any& );
108
109namespace {
110
111struct ExportTable
112{
113 const char* pPropertyName;
114 sal_uInt16 const nNamespace;
115 sal_uInt16 nToken;
116 convert_t const aConverter;
117};
118
119}
120
121static void lcl_export( const Reference<XPropertySet>& rPropertySet,
122 SvXMLExport& rExport,
123 const ExportTable* pTable );
124
125#define TABLE_ENTRY(NAME,NAMESPACE,TOKEN,CONVERTER) { NAME,XML_NAMESPACE_##NAMESPACE,xmloff::token::XML_##TOKEN, CONVERTER }
126#define TABLE_END { nullptr, 0, 0, nullptr }
127
128// any conversion functions
129static OUString xforms_string( const Any& );
130static OUString xforms_bool( const Any& );
131static OUString xforms_whitespace( const Any& );
132template<typename T, void (*FUNC)( OUStringBuffer&, T )> static OUString xforms_convert( const Any& );
133template<typename T, void (*FUNC)( OUStringBuffer&, const T& )> static OUString xforms_convertRef( const Any& );
134
135static void xforms_formatDate( OUStringBuffer& aBuffer, const util::Date& aDate );
136static void xforms_formatTime( OUStringBuffer& aBuffer, const css::util::Time& aTime );
137static void xforms_formatDateTime( OUStringBuffer& aBuffer, const util::DateTime& aDateTime );
138
139static void convertNumber(OUStringBuffer & b, sal_Int32 n) {
140 b.append(n);
141}
142
143convert_t const xforms_int32 = &xforms_convert<sal_Int32,&convertNumber>;
144convert_t const xforms_double = &xforms_convert<double,&::sax::Converter::convertDouble>;
145convert_t const xforms_dateTime = &xforms_convertRef<util::DateTime,&xforms_formatDateTime>;
146convert_t const xforms_date = &xforms_convertRef<util::Date,&xforms_formatDate>;
147convert_t const xforms_time = &xforms_convertRef<css::util::Time,&xforms_formatTime>;
148
149// other functions
150static OUString lcl_getXSDType( SvXMLExport const & rExport,
151 const Reference<XPropertySet>& xType );
152
153
154// the model
155
156
157const ExportTable aXFormsModelTable[] =
158{
159 TABLE_ENTRY( "ID", NONE, ID, xforms_string ),
160 TABLE_ENTRY( "SchemaRef", NONE, SCHEMA, xforms_string ),
162};
163
165 const Reference<XPropertySet>& xModelPropSet )
166{
167 // no model -> don't do anything!
168 Reference<css::xforms::XModel> xModel( xModelPropSet, UNO_QUERY );
169 if( ! xModel.is() || ! xModelPropSet.is() )
170 return;
171
172 lcl_export( xModelPropSet, rExport, aXFormsModelTable );
173 SvXMLElementExport aModelElement( rExport, XML_NAMESPACE_XFORMS, XML_MODEL,
174 true, true );
175
176 // instances
177 Reference<XIndexAccess> xInstances( xModel->getInstances(),
178 UNO_QUERY_THROW);
179 sal_Int32 nCount = xInstances->getCount();
180 sal_Int32 i = 0;
181 for( i = 0; i < nCount; i++ )
182 {
183 Sequence<PropertyValue> aInstance;
184 xInstances->getByIndex( i ) >>= aInstance;
185 exportXFormsInstance( rExport, aInstance );
186 }
187
188
189 // bindings
190 Reference<XIndexAccess> xBindings( xModel->getBindings(), UNO_QUERY_THROW);
191 nCount = xBindings->getCount();
192 for( i = 0; i < nCount; i++ )
193 {
194 Reference<XPropertySet> aBinding( xBindings->getByIndex( i ),
195 UNO_QUERY_THROW );
196 exportXFormsBinding( rExport, aBinding );
197 }
198
199 // submissions
200 Reference<XIndexAccess> xSubmissions( xModel->getSubmissions(),
201 UNO_QUERY_THROW );
202 nCount = xSubmissions->getCount();
203 for( i = 0; i < nCount; i++ )
204 {
205 Reference<XPropertySet> xSubmission( xSubmissions->getByIndex( i ),
206 UNO_QUERY_THROW );
207 exportXFormsSubmission( rExport, xSubmission );
208 }
209
210 // schemas
211 exportXFormsSchemas( rExport, xModel );
212}
213
214
215// the instance
216
217
219 const Sequence<PropertyValue>& xInstance )
220{
221 OUString sId;
222 OUString sURL;
224
225 for( const auto& rProp : xInstance )
226 {
227 OUString sName = rProp.Name;
228 const Any& rAny = rProp.Value;
229 if ( sName == "ID" )
230 rAny >>= sId;
231 else if ( sName == "URL" )
232 rAny >>= sURL;
233 else if ( sName == "Instance" )
234 rAny >>= xDoc;
235 }
236
237 if( !sId.isEmpty() )
239
240 if( !sURL.isEmpty() )
241 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_SRC, sURL );
242
244 true, true );
245 rExport.IgnorableWhitespace();
246 if( xDoc.is() )
247 {
248 exportDom( rExport, xDoc );
249 }
250}
251
252
253// the binding
254
255
256const ExportTable aXFormsBindingTable[] =
257{
258 TABLE_ENTRY( "BindingID", NONE, ID, xforms_string ),
259 TABLE_ENTRY( "BindingExpression", NONE, NODESET, xforms_string ),
260 TABLE_ENTRY( "ReadonlyExpression", NONE, READONLY, xforms_string ),
261 TABLE_ENTRY( "RelevantExpression", NONE, RELEVANT, xforms_string ),
262 TABLE_ENTRY( "RequiredExpression", NONE, REQUIRED, xforms_string ),
263 TABLE_ENTRY( "ConstraintExpression", NONE, CONSTRAINT, xforms_string ),
264 TABLE_ENTRY( "CalculateExpression", NONE, CALCULATE, xforms_string ),
265 // type handled separately, for type name <-> XSD type conversion
266 // TABLE_ENTRY( "Type", NONE, TYPE, xforms_string ),
268};
269
271 const Reference<XPropertySet>& xBinding )
272{
273 // name check; generate binding ID if necessary
274 {
275 OUString sName;
276 xBinding->getPropertyValue( "BindingID" ) >>= sName;
277 if( sName.isEmpty() )
278 {
279 // if we don't have a name yet, generate one on the fly
280 sal_Int64 nId = reinterpret_cast<sal_uInt64>( xBinding.get() );
281 sName = "bind_" + OUString::number( nId , 16 );
282 xBinding->setPropertyValue( "BindingID", Any(sName));
283 }
284 }
285
286 lcl_export( xBinding, rExport, aXFormsBindingTable );
287
288 // handle type attribute
289 {
290 OUString sTypeName;
291 xBinding->getPropertyValue( "Type" ) >>= sTypeName;
292
293 try
294 {
295 // now get type, and determine whether it's a standard type. If
296 // so, export the XSD name
298 xBinding->getPropertyValue( "Model" ),
299 UNO_QUERY );
301 xModel.is() ? xModel->getDataTypeRepository() : Reference<XDataTypeRepository>() );
302 if( xRepository.is() )
303 {
304 Reference<XPropertySet> xDataType =
305 xRepository->getDataType( sTypeName );
306
307 // if it's a basic data type, write out the XSD name
308 // for the XSD type class
309 bool bIsBasic = false;
310 xDataType->getPropertyValue( "IsBasic" ) >>= bIsBasic;
311 if( bIsBasic )
312 sTypeName = lcl_getXSDType( rExport, xDataType );
313 }
314 }
315 catch( Exception& )
316 {
317 ; // ignore; just use typename
318 }
319
320 // now that we have the proper type name, write out the attribute
321 if( !sTypeName.isEmpty() )
322 {
324 sTypeName );
325 }
326 }
327
328 // we need to ensure all the namespaces in the binding will work correctly.
329 // to do so, we will write out all missing namespace declaractions.
330 const SvXMLNamespaceMap& rMap = rExport.GetNamespaceMap();
331 Reference<XNameAccess> xNamespaces(
332 xBinding->getPropertyValue( "ModelNamespaces" ), UNO_QUERY);
333 if( xNamespaces.is() )
334 {
335 // iterate over Prefixes for this binding
336 const Sequence<OUString> aPrefixes = xNamespaces->getElementNames();
337 for( const OUString& rPrefix : aPrefixes )
338 {
339 OUString sURI;
340 xNamespaces->getByName( rPrefix ) >>= sURI;
341
342 // check whether prefix/URI pair is in map; else write declaration
343 // (we don't need to change the map, since this element has no
344 // other content)
345 sal_uInt16 nKey = rMap.GetKeyByPrefix( rPrefix );
346 if( nKey == XML_NAMESPACE_UNKNOWN ||
347 rMap.GetNameByKey( nKey ) != sURI )
348 {
349 // add declaration if it doesn't already exist
350 SvXMLAttributeList& rAttrList = rExport.GetAttrList();
351 OUString sName = "xmlns:" + rPrefix;
352 sal_Int16 nFound = rAttrList.GetIndexByName(sName);
353 // duplicate xmlns:script, http://openoffice.org/2000/script seen
354 assert(nFound == -1 || rAttrList.getValueByIndex(nFound) == sURI);
355 if (nFound != -1)
356 continue;
357 rAttrList.AddAttribute(sName, sURI);
358 }
359 }
360 }
361
363 true, true );
364}
365
366
367// the submission
368
369
370const ExportTable aXFormsSubmissionTable[] =
371{
372 TABLE_ENTRY( "ID", NONE, ID, xforms_string ),
373 TABLE_ENTRY( "Bind", NONE, BIND, xforms_string ),
374 TABLE_ENTRY( "Ref", NONE, REF, xforms_string ),
375 TABLE_ENTRY( "Action", NONE, ACTION, xforms_string ),
376 TABLE_ENTRY( "Method", NONE, METHOD, xforms_string ),
377 TABLE_ENTRY( "Version", NONE, VERSION, xforms_string ),
378 TABLE_ENTRY( "Indent", NONE, INDENT, xforms_bool ),
379 TABLE_ENTRY( "MediaType", NONE, MEDIATYPE, xforms_string ),
380 TABLE_ENTRY( "Encoding", NONE, ENCODING, xforms_string ),
381 TABLE_ENTRY( "OmitXmlDeclaration", NONE, OMIT_XML_DECLARATION, xforms_bool ),
382 TABLE_ENTRY( "Standalone", NONE, STANDALONE, xforms_bool ),
383 TABLE_ENTRY( "CDataSectionElement", NONE, CDATA_SECTION_ELEMENTS, xforms_string ),
384 TABLE_ENTRY( "Replace", NONE, REPLACE, xforms_string ),
385 TABLE_ENTRY( "Separator", NONE, SEPARATOR, xforms_string ),
386 TABLE_ENTRY( "IncludeNamespacePrefixes", NONE, INCLUDENAMESPACEPREFIXES, xforms_string ),
388};
389
391 const Reference<XPropertySet>& xSubmission )
392{
393 lcl_export( xSubmission, rExport, aXFormsSubmissionTable );
395 true, true );
396}
397
398
399// export data types as XSD schema
400
401
402const ExportTable aDataTypeFacetTable[] =
403{
404 TABLE_ENTRY( "Length", XSD, LENGTH, xforms_int32 ),
405 TABLE_ENTRY( "MinLength", XSD, MINLENGTH, xforms_int32 ),
406 TABLE_ENTRY( "MaxLength", XSD, MAXLENGTH, xforms_int32 ),
407 TABLE_ENTRY( "MinInclusiveInt", XSD, MININCLUSIVE, xforms_int32 ),
408 TABLE_ENTRY( "MinExclusiveInt", XSD, MINEXCLUSIVE, xforms_int32 ),
409 TABLE_ENTRY( "MaxInclusiveInt", XSD, MAXINCLUSIVE, xforms_int32 ),
410 TABLE_ENTRY( "MaxExclusiveInt", XSD, MAXEXCLUSIVE, xforms_int32 ),
411 TABLE_ENTRY( "MinInclusiveDouble", XSD, MININCLUSIVE, xforms_double ),
412 TABLE_ENTRY( "MinExclusiveDouble", XSD, MINEXCLUSIVE, xforms_double ),
413 TABLE_ENTRY( "MaxInclusiveDouble", XSD, MAXINCLUSIVE, xforms_double ),
414 TABLE_ENTRY( "MaxExclusiveDouble", XSD, MAXEXCLUSIVE, xforms_double ),
415 TABLE_ENTRY( "MinInclusiveDate", XSD, MININCLUSIVE, xforms_date ),
416 TABLE_ENTRY( "MinExclusiveDate", XSD, MINEXCLUSIVE, xforms_date ),
417 TABLE_ENTRY( "MaxInclusiveDate", XSD, MAXINCLUSIVE, xforms_date ),
418 TABLE_ENTRY( "MaxExclusiveDate", XSD, MAXEXCLUSIVE, xforms_date ),
419 TABLE_ENTRY( "MinInclusiveTime", XSD, MININCLUSIVE, xforms_time ),
420 TABLE_ENTRY( "MinExclusiveTime", XSD, MINEXCLUSIVE, xforms_time ),
421 TABLE_ENTRY( "MaxInclusiveTime", XSD, MAXINCLUSIVE, xforms_time ),
422 TABLE_ENTRY( "MaxExclusiveTime", XSD, MAXEXCLUSIVE, xforms_time ),
423 TABLE_ENTRY( "MinInclusiveDateTime", XSD, MININCLUSIVE, xforms_dateTime ),
424 TABLE_ENTRY( "MinExclusiveDateTime", XSD, MINEXCLUSIVE, xforms_dateTime ),
425 TABLE_ENTRY( "MaxInclusiveDateTime", XSD, MAXINCLUSIVE, xforms_dateTime ),
426 TABLE_ENTRY( "MaxExclusiveDateTime", XSD, MAXEXCLUSIVE, xforms_dateTime ),
427 TABLE_ENTRY( "Pattern", XSD, PATTERN, xforms_string ),
428 // ??? XML_ENUMERATION,
429 TABLE_ENTRY( "WhiteSpace", XSD, WHITESPACE, xforms_whitespace ),
430 TABLE_ENTRY( "TotalDigits", XSD, TOTALDIGITS, xforms_int32 ),
431 TABLE_ENTRY( "FractionDigits", XSD, FRACTIONDIGITS, xforms_int32 ),
433};
434
435// export facets through table; use the same table as lcl_export does
437 const Reference<XPropertySet>& rPropertySet,
438 const ExportTable* pTable )
439{
440 Reference<XPropertySetInfo> xInfo = rPropertySet->getPropertySetInfo();
441 for( const ExportTable* pCurrent = pTable;
442 pCurrent->pPropertyName != nullptr;
443 pCurrent++ )
444 {
445 OUString sName( OUString::createFromAscii( pCurrent->pPropertyName ) );
446 if( xInfo->hasPropertyByName( sName ) )
447 {
448 OUString sValue = (*pCurrent->aConverter)(
449 rPropertySet->getPropertyValue( sName ) );
450
451 if( !sValue.isEmpty() )
452 {
453 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_VALUE, sValue );
454 SvXMLElementExport aFacet(
455 rExport,
456 pCurrent->nNamespace,
457 static_cast<XMLTokenEnum>( pCurrent->nToken ),
458 true, true );
459 }
460 }
461 }
462}
463
464static OUString lcl_getXSDType( SvXMLExport const & rExport,
465 const Reference<XPropertySet>& xType )
466{
467 // we use string as default...
469
470 sal_uInt16 nDataTypeClass = 0;
471 xType->getPropertyValue( "TypeClass" ) >>= nDataTypeClass;
472 switch( nDataTypeClass )
473 {
474 case css::xsd::DataTypeClass::STRING:
476 break;
477 case css::xsd::DataTypeClass::anyURI:
479 break;
480 case css::xsd::DataTypeClass::DECIMAL:
482 break;
483 case css::xsd::DataTypeClass::DOUBLE:
485 break;
486 case css::xsd::DataTypeClass::FLOAT:
488 break;
489 case css::xsd::DataTypeClass::BOOLEAN:
491 break;
492 case css::xsd::DataTypeClass::DATETIME:
494 break;
495 case css::xsd::DataTypeClass::TIME:
497 break;
498 case css::xsd::DataTypeClass::DATE:
500 break;
501 case css::xsd::DataTypeClass::gYear:
503 break;
504 case css::xsd::DataTypeClass::gDay:
505 eToken = XML_DAY;
506 break;
507 case css::xsd::DataTypeClass::gMonth:
509 break;
510 case css::xsd::DataTypeClass::DURATION:
511 case css::xsd::DataTypeClass::gYearMonth:
512 case css::xsd::DataTypeClass::gMonthDay:
513 case css::xsd::DataTypeClass::hexBinary:
514 case css::xsd::DataTypeClass::base64Binary:
515 case css::xsd::DataTypeClass::QName:
516 case css::xsd::DataTypeClass::NOTATION:
517 default:
518 OSL_FAIL( "unknown data type" );
519 }
520
522 GetXMLToken( eToken ) );
523}
524
525static void lcl_exportDataType( SvXMLExport& rExport,
526 const Reference<XPropertySet>& xType )
527{
528 // we do not need to export basic types; exit if we have one
529 bool bIsBasic = false;
530 xType->getPropertyValue( "IsBasic" ) >>= bIsBasic;
531 if( bIsBasic )
532 return;
533
534 // no basic type -> export
535
536 // <xsd:simpleType name="...">
537 OUString sName;
538 xType->getPropertyValue( "Name" ) >>= sName;
540 SvXMLElementExport aSimpleType( rExport,
542 true, true );
543
544 // <xsd:restriction base="xsd:...">
546 lcl_getXSDType( rExport, xType ) );
547 SvXMLElementExport aRestriction( rExport,
550 true, true );
551
552 // export facets
554 xType,
556}
557
559 const Reference<css::xforms::XModel>& xModel )
560{
561 // TODO: for now, we'll fake this...
562 {
563 SvXMLElementExport aSchemaElem( rExport, XML_NAMESPACE_XSD, XML_SCHEMA,
564 true, true );
565
566 // now get data type repository, and export
567 Reference<XEnumerationAccess> xTypes = xModel->getDataTypeRepository();
568 if( xTypes.is() )
569 {
570 Reference<XEnumeration> xEnum = xTypes->createEnumeration();
571 SAL_WARN_IF( !xEnum.is(), "xmloff", "no enum?" );
572 while( xEnum->hasMoreElements() )
573 {
574 Reference<XPropertySet> xType( xEnum->nextElement(), UNO_QUERY );
575 lcl_exportDataType( rExport, xType );
576 }
577 }
578 }
579
580 // export other, 'foreign' schemas
581 Reference<XPropertySet> xPropSet( xModel, UNO_QUERY );
582 if( xPropSet.is() )
583 {
584 Reference<XDocument> xDocument(
585 xPropSet->getPropertyValue( "ForeignSchema" ),
586 UNO_QUERY );
587
588 if( xDocument.is() )
589 exportDom( rExport, xDocument );
590 }
591}
592
593
594// helper functions
595
596
597static void lcl_export( const Reference<XPropertySet>& rPropertySet,
598 SvXMLExport& rExport,
599 const ExportTable* pTable )
600{
601 for( const ExportTable* pCurrent = pTable;
602 pCurrent->pPropertyName != nullptr;
603 pCurrent++ )
604 {
605 Any aAny = rPropertySet->getPropertyValue(
606 OUString::createFromAscii( pCurrent->pPropertyName ) );
607 OUString sValue = (*pCurrent->aConverter)( aAny );
608
609 if( !sValue.isEmpty() )
610 rExport.AddAttribute(
611 pCurrent->nNamespace,
612 static_cast<XMLTokenEnum>( pCurrent->nToken ),
613 sValue );
614 }
615}
616
617
618// any conversion functions
619
620
621template<typename T, void (*FUNC)( OUStringBuffer&, T )>
622OUString xforms_convert( const Any& rAny )
623{
624 OUStringBuffer aBuffer;
625 T aData = T();
626 if( rAny >>= aData )
627 {
628 FUNC( aBuffer, aData );
629 }
630 return aBuffer.makeStringAndClear();
631}
632
633template<typename T, void (*FUNC)( OUStringBuffer&, const T& )>
634OUString xforms_convertRef( const Any& rAny )
635{
636 OUStringBuffer aBuffer;
637 T aData;
638 if( rAny >>= aData )
639 {
640 FUNC( aBuffer, aData );
641 }
642 return aBuffer.makeStringAndClear();
643}
644
645OUString xforms_string( const Any& rAny )
646{
647 OUString aResult;
648 rAny >>= aResult;
649 return aResult;
650}
651
652OUString xforms_bool( const Any& rAny )
653{
654 bool bResult = bool();
655 if( rAny >>= bResult )
656 return GetXMLToken( bResult ? XML_TRUE : XML_FALSE );
657 OSL_FAIL( "expected boolean value" );
658 return OUString();
659}
660
661void xforms_formatDate( OUStringBuffer& aBuffer, const util::Date& rDate )
662{
663 aBuffer.append( OUString::number( rDate.Year ) +
664 "-" + OUString::number( rDate.Month ) +
665 "-" + OUString::number( rDate.Day ) );
666}
667
668void xforms_formatTime( OUStringBuffer& aBuffer, const css::util::Time& rTime )
669{
670 Duration aDuration;
671 aDuration.Hours = rTime.Hours;
672 aDuration.Minutes = rTime.Minutes;
673 aDuration.Seconds = rTime.Seconds;
674 aDuration.NanoSeconds = rTime.NanoSeconds;
676}
677
678void xforms_formatDateTime( OUStringBuffer& aBuffer, const util::DateTime& aDateTime )
679{
680 ::sax::Converter::convertDateTime(aBuffer, aDateTime, nullptr);
681}
682
683OUString xforms_whitespace( const Any& rAny )
684{
685 OUString sResult;
686 sal_uInt16 n = sal_uInt16();
687 if( rAny >>= n )
688 {
689 switch( n )
690 {
691 case css::xsd::WhiteSpaceTreatment::Preserve:
692 sResult = GetXMLToken( XML_PRESERVE );
693 break;
694 case css::xsd::WhiteSpaceTreatment::Replace:
695 sResult = GetXMLToken( XML_REPLACE );
696 break;
697 case css::xsd::WhiteSpaceTreatment::Collapse:
698 sResult = GetXMLToken( XML_COLLAPSE );
699 break;
700 }
701 }
702 return sResult;
703}
704
705
707static OUString lcl_getXFormsBindName( const Reference<XPropertySet>& xBinding )
708{
709 OUString sProp( "BindingID" );
710
711 OUString sReturn;
712 if( xBinding.is() &&
713 xBinding->getPropertySetInfo()->hasPropertyByName( sProp ) )
714 {
715 xBinding->getPropertyValue( sProp ) >>= sReturn;
716 }
717 return sReturn;
718}
719
720// return name of binding
722{
723 Reference<XBindableValue> xBindable( xControl, UNO_QUERY );
724 return xBindable.is()
726 Reference<XPropertySet>( xBindable->getValueBinding(), UNO_QUERY ))
727 : OUString();
728}
729
730// return name of list binding
732{
733 Reference<XListEntrySink> xListEntrySink( xControl, UNO_QUERY );
734 return xListEntrySink.is()
736 Reference<XPropertySet>( xListEntrySink->getListEntrySource(),
737 UNO_QUERY ) )
738 : OUString();
739}
740
742{
743 OUString sReturn;
744
745 Reference<XSubmissionSupplier> xSubmissionSupplier( xBinding, UNO_QUERY );
746 if( xSubmissionSupplier.is() )
747 {
748 Reference<XPropertySet> xPropertySet(
749 xSubmissionSupplier->getSubmission(), UNO_QUERY );
750 OUString sProp( "ID" );
751 if( xPropertySet.is() &&
752 xPropertySet->getPropertySetInfo()->hasPropertyByName( sProp ) )
753 {
754 xPropertySet->getPropertyValue( sProp ) >>= sReturn;
755 }
756 }
757
758 return sReturn;
759}
760
762{
763 _out_rSettings = Sequence< PropertyValue >();
764
765 OSL_PRECOND( _rXForms.is(), "getXFormsSettings: invalid XForms container!" );
766 if ( !_rXForms.is() )
767 return;
768
769 try
770 {
771 // we want to export some special properties of our XForms models as config-item-map-named,
772 // which implies we need a PropertyValue whose value is an XNameAccess, whose keys
773 // are the names of the XForm models, and which in turn provides named sequences of
774 // PropertyValues - which denote the actual property values of the given named model.
775
776 const Sequence< OUString > aModelNames( _rXForms->getElementNames() );
777
778 Reference< XNameContainer > xModelSettings = document::NamedPropertyValues::create( comphelper::getProcessComponentContext() );
779
780 for ( auto const & modelName : aModelNames )
781 {
782 Reference< XPropertySet > xModelProps( _rXForms->getByName( modelName ), UNO_QUERY_THROW );
783
784 static constexpr OUStringLiteral sExternalData = u"ExternalData";
786 sExternalData, xModelProps->getPropertyValue(sExternalData)) };
787
788 xModelSettings->insertByName( modelName, Any( aModelSettings ) );
789 }
790
791 if ( xModelSettings->hasElements() )
792 {
793 _out_rSettings = { comphelper::makePropertyValue("XFormModels", xModelSettings) };
794 }
795 }
796 catch( const Exception& )
797 {
798 DBG_UNHANDLED_EXCEPTION("xmloff");
799 }
800}
801
802/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void exportDom(SvXMLExport &rExport, const Reference< XDocument > &xDocument)
Definition: DomExport.cxx:243
const char * pPropertyName
sal_Int16 GetIndexByName(const OUString &rName) const
Definition: attrlist.cxx:177
void AddAttribute(const OUString &sName, const OUString &sValue)
Definition: attrlist.cxx:110
virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) override
Definition: attrlist.cxx:69
const SvXMLNamespaceMap & GetNamespaceMap() const
Definition: xmlexp.hxx:390
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
Definition: xmlexp.cxx:911
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:416
SvXMLAttributeList & GetAttrList()
Definition: xmlexp.hxx:379
void IgnorableWhitespace()
Definition: xmlexp.cxx:2194
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
const OUString & GetNameByKey(sal_uInt16 nKey) const
sal_uInt16 GetKeyByPrefix(const OUString &rPrefix) const
static void convertDateTime(OUStringBuffer &rBuffer, const css::util::DateTime &rDateTime, sal_Int16 const *pTimeZoneOffset, bool bAddTimeIf0AM=false)
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
const bool READONLY
float u
sal_Int64 n
#define SAL_WARN_IF(condition, area, stream)
#define SEPARATOR
const char * sName
constexpr OUStringLiteral aData
NONE
@ Exception
class SAL_NO_VTABLE XPropertySet
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
const sal_uInt16 XML_NAMESPACE_NONE
const sal_uInt16 XML_NAMESPACE_UNKNOWN
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3517
sal_Int16 nId
DefTokenId nToken
#define VERSION
OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace
Reference< XModel > xModel
OUString sId
constexpr OUStringLiteral PATTERN
std::unique_ptr< char[]> aBuffer
static void xforms_formatDateTime(OUStringBuffer &aBuffer, const util::DateTime &aDateTime)
static OUString lcl_getXFormsBindName(const Reference< XPropertySet > &xBinding)
return name of Binding
static void exportXFormsInstance(SvXMLExport &, const Sequence< PropertyValue > &)
static OUString xforms_whitespace(const Any &)
#define TABLE_END
void getXFormsSettings(const Reference< XNameAccess > &_rXForms, Sequence< PropertyValue > &_out_rSettings)
static OUString lcl_getXSDType(SvXMLExport const &rExport, const Reference< XPropertySet > &xType)
static void exportXFormsBinding(SvXMLExport &, const Reference< XPropertySet > &)
static OUString xforms_convert(const Any &)
static void lcl_export(const Reference< XPropertySet > &rPropertySet, SvXMLExport &rExport, const ExportTable *pTable)
OUString getXFormsSubmissionName(const Reference< XPropertySet > &xBinding)
OUString getXFormsBindName(const Reference< XPropertySet > &xControl)
convert_t const xforms_dateTime
const ExportTable aXFormsModelTable[]
static void xforms_formatTime(OUStringBuffer &aBuffer, const css::util::Time &aTime)
static void exportXFormsSubmission(SvXMLExport &, const Reference< XPropertySet > &)
convert_t const xforms_time
const ExportTable aXFormsBindingTable[]
static void lcl_exportDataType(SvXMLExport &rExport, const Reference< XPropertySet > &xType)
static OUString xforms_bool(const Any &)
convert_t const xforms_int32
const ExportTable aDataTypeFacetTable[]
static OUString xforms_string(const Any &)
const ExportTable aXFormsSubmissionTable[]
static OUString xforms_convertRef(const Any &)
static void xforms_formatDate(OUStringBuffer &aBuffer, const util::Date &aDate)
static void exportXFormsSchemas(SvXMLExport &, const Reference< css::xforms::XModel > &)
OUString getXFormsListBindName(const Reference< XPropertySet > &xControl)
static void lcl_exportDataTypeFacets(SvXMLExport &rExport, const Reference< XPropertySet > &rPropertySet, const ExportTable *pTable)
convert_t const xforms_double
void exportXForms(SvXMLExport &rExport)
export an XForms model.
OUString(* convert_t)(const Any &)
static void convertNumber(OUStringBuffer &b, sal_Int32 n)
void exportXFormsModel(SvXMLExport &rExport, const Reference< XPropertySet > &xModelPropSet)
#define TABLE_ENTRY(NAME, NAMESPACE, TOKEN, CONVERTER)
convert_t const xforms_date
constexpr sal_uInt16 XML_NAMESPACE_XSD
constexpr sal_uInt16 XML_NAMESPACE_XFORMS
XMLTokenEnum eToken
Definition: xmltoken.cxx:40