1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26
27 #include "xmloff/xformsexport.hxx"
28
29 #include "XFormsModelExport.hxx"
30 #include "xformsapi.hxx"
31
32 #include <xmloff/xmlexp.hxx>
33 #include <xmloff/xmltoken.hxx>
34 #include "xmloff/xmlnmspe.hxx"
35 #include <xmloff/nmspmap.hxx>
36 #include "DomExport.hxx"
37 #include <xmloff/xmluconv.hxx>
38 #include <comphelper/componentcontext.hxx>
39 #include <comphelper/processfactory.hxx>
40
41 #include "tools/debug.hxx"
42 #include <tools/diagnose_ex.h>
43 #include <com/sun/star/container/XIndexAccess.hpp>
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #include <com/sun/star/xml/dom/XDocument.hpp>
46 #include <com/sun/star/form/binding/XValueBinding.hpp>
47 #include <com/sun/star/form/binding/XBindableValue.hpp>
48 #include <com/sun/star/form/binding/XListEntrySink.hpp>
49 #include <com/sun/star/form/binding/XListEntrySource.hpp>
50 #include <com/sun/star/form/submission/XSubmissionSupplier.hpp>
51 #include <com/sun/star/xforms/XModel.hpp>
52 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
53 #include <com/sun/star/xforms/XFormsSupplier.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/container/XEnumerationAccess.hpp>
56 #include <com/sun/star/container/XEnumeration.hpp>
57 #include <com/sun/star/container/XNameContainer.hpp>
58 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
59 #include <com/sun/star/xsd/DataTypeClass.hpp>
60 #include <com/sun/star/xsd/XDataType.hpp>
61 #include <com/sun/star/util/Date.hpp>
62 #include <com/sun/star/util/Time.hpp>
63 #include <com/sun/star/util/DateTime.hpp>
64
65 using namespace com::sun::star;
66 using namespace com::sun::star::uno;
67 using namespace xmloff::token;
68
69 using rtl::OUString;
70 using rtl::OUStringBuffer;
71 using com::sun::star::beans::XPropertySet;
72 using com::sun::star::beans::XPropertySetInfo;
73 using com::sun::star::container::XIndexAccess;
74 using com::sun::star::container::XNameAccess;
75 using com::sun::star::container::XNameContainer;
76 using com::sun::star::container::XEnumerationAccess;
77 using com::sun::star::container::XEnumeration;
78 using com::sun::star::xml::dom::XDocument;
79 using com::sun::star::form::binding::XValueBinding;
80 using com::sun::star::form::binding::XBindableValue;
81 using com::sun::star::form::binding::XListEntrySink;
82 using com::sun::star::form::submission::XSubmissionSupplier;
83 using com::sun::star::beans::PropertyValue;
84 using com::sun::star::xsd::XDataType;
85 using com::sun::star::xforms::XDataTypeRepository;
86 using com::sun::star::xforms::XFormsSupplier;
87 using com::sun::star::util::Date;
88 using com::sun::star::util::DateTime;
89
exportXForms(SvXMLExport & rExport)90 void exportXForms( SvXMLExport& rExport )
91 {
92 Reference<XFormsSupplier> xSupplier( rExport.GetModel(), UNO_QUERY );
93 if( xSupplier.is() )
94 {
95 Reference<XNameContainer> xForms = xSupplier->getXForms();
96 if( xForms.is() )
97 {
98 Sequence<OUString> aNames = xForms->getElementNames();
99 const OUString* pNames = aNames.getConstArray();
100 sal_Int32 nNames = aNames.getLength();
101
102 for( sal_Int32 n = 0; n < nNames; n++ )
103 {
104 Reference<XPropertySet> xModel( xForms->getByName( pNames[n] ),
105 UNO_QUERY );
106 exportXFormsModel( rExport, xModel );
107 }
108 }
109 }
110 }
111
112
113 void exportXFormsInstance( SvXMLExport&, const Sequence<PropertyValue>& );
114 void exportXFormsBinding( SvXMLExport&, const Reference<XPropertySet>& );
115 void exportXFormsSubmission( SvXMLExport&, const Reference<XPropertySet>& );
116 void exportXFormsSchemas( SvXMLExport&, const Reference<com::sun::star::xforms::XModel>& );
117
118
119 typedef OUString (*convert_t)( const Any& );
120 typedef struct
121 {
122 const sal_Char* pPropertyName;
123 sal_uInt16 nPropertyNameLength;
124 sal_uInt16 nNamespace;
125 sal_uInt16 nToken;
126 convert_t aConverter;
127 } ExportTable;
128 void lcl_export( const Reference<XPropertySet>& rPropertySet,
129 SvXMLExport& rExport,
130 const ExportTable* pTable );
131
132 #define TABLE_ENTRY(NAME,NAMESPACE,TOKEN,CONVERTER) { NAME,sizeof(NAME)-1,XML_NAMESPACE_##NAMESPACE,xmloff::token::XML_##TOKEN, CONVERTER }
133 #define TABLE_END { NULL, 0, 0, 0, NULL }
134
135
136 // any conversion functions
137 OUString lcl_string( const Any& );
138 OUString lcl_bool( const Any& );
139 OUString lcl_whitespace( const Any& );
140 template<typename T, void (*FUNC)( OUStringBuffer&, T )> OUString lcl_convert( const Any& );
141 template<typename T, void (*FUNC)( OUStringBuffer&, const T& )> OUString lcl_convertRef( const Any& );
142
143 void lcl_formatDate( OUStringBuffer& aBuffer, const Date& aDate );
144 void lcl_formatTime( OUStringBuffer& aBuffer, const com::sun::star::util::Time& aTime );
145 void lcl_formatDateTime( OUStringBuffer& aBuffer, const DateTime& aDateTime );
146
147 convert_t lcl_int32 = &lcl_convert<sal_Int32,&SvXMLUnitConverter::convertNumber>;
148 convert_t lcl_double = &lcl_convert<double,&SvXMLUnitConverter::convertDouble>;
149 convert_t lcl_dateTime = &lcl_convertRef<DateTime,&lcl_formatDateTime>;
150 convert_t lcl_date = &lcl_convertRef<Date,&lcl_formatDate>;
151 convert_t lcl_time = &lcl_convertRef<com::sun::star::util::Time,&lcl_formatTime>;
152
153 // other functions
154 OUString lcl_getXSDType( SvXMLExport& rExport,
155 const Reference<XPropertySet>& xType );
156
157
158 //
159 // the model
160 //
161
162 static const ExportTable aXFormsModelTable[] =
163 {
164 TABLE_ENTRY( "ID", NONE, ID, lcl_string ),
165 TABLE_ENTRY( "SchemaRef", NONE, SCHEMA, lcl_string ),
166 TABLE_END
167 };
168
exportXFormsModel(SvXMLExport & rExport,const Reference<XPropertySet> & xModelPropSet)169 void exportXFormsModel( SvXMLExport& rExport,
170 const Reference<XPropertySet>& xModelPropSet )
171 {
172 // no model -> don't do anything!
173 Reference<com::sun::star::xforms::XModel> xModel( xModelPropSet, UNO_QUERY );
174 if( ! xModel.is() || ! xModelPropSet.is() )
175 return;
176
177 lcl_export( xModelPropSet, rExport, aXFormsModelTable );
178 SvXMLElementExport aModelElement( rExport, XML_NAMESPACE_XFORMS, XML_MODEL,
179 sal_True, sal_True );
180
181 // instances
182 Reference<XIndexAccess> xInstances( xModel->getInstances(),
183 UNO_QUERY_THROW);
184 sal_Int32 nCount = xInstances->getCount();
185 sal_Int32 i = 0;
186 for( i = 0; i < nCount; i++ )
187 {
188 Sequence<PropertyValue> aInstance;
189 xInstances->getByIndex( i ) >>= aInstance;
190 exportXFormsInstance( rExport, aInstance );
191 }
192
193
194 // bindings
195 Reference<XIndexAccess> xBindings( xModel->getBindings(), UNO_QUERY_THROW);
196 nCount = xBindings->getCount();
197 for( i = 0; i < nCount; i++ )
198 {
199 Reference<XPropertySet> aBinding( xBindings->getByIndex( i ),
200 UNO_QUERY_THROW );
201 exportXFormsBinding( rExport, aBinding );
202 }
203
204 // submissions
205 Reference<XIndexAccess> xSubmissions( xModel->getSubmissions(),
206 UNO_QUERY_THROW );
207 nCount = xSubmissions->getCount();
208 for( i = 0; i < nCount; i++ )
209 {
210 Reference<XPropertySet> xSubmission( xSubmissions->getByIndex( i ),
211 UNO_QUERY_THROW );
212 exportXFormsSubmission( rExport, xSubmission );
213 }
214
215 // schemas
216 exportXFormsSchemas( rExport, xModel );
217 }
218
219 //
220 // the instance
221 //
222
223 static const ExportTable aXFormsInstanceTable[] =
224 {
225 TABLE_ENTRY( "InstanceURL", NONE, SRC, lcl_string ),
226 TABLE_END
227 };
228
exportXFormsInstance(SvXMLExport & rExport,const Sequence<PropertyValue> & xInstance)229 void exportXFormsInstance( SvXMLExport& rExport,
230 const Sequence<PropertyValue>& xInstance )
231 {
232 OUString sId;
233 OUString sURL;
234 Reference<XDocument> xDoc;
235
236 const PropertyValue* pInstance = xInstance.getConstArray();
237 sal_Int32 nCount = xInstance.getLength();
238 for( sal_Int32 i = 0; i < nCount; i++ )
239 {
240 OUString sName = pInstance[i].Name;
241 const Any& rAny = pInstance[i].Value;
242 if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ID") ) )
243 rAny >>= sId;
244 else if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("URL") ) )
245 rAny >>= sURL;
246 else if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Instance") ))
247 rAny >>= xDoc;
248 }
249
250 if( sId.getLength() > 0 )
251 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_ID, sId );
252
253 if( sURL.getLength() > 0 )
254 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_SRC, sURL );
255
256 SvXMLElementExport aElem( rExport, XML_NAMESPACE_XFORMS, XML_INSTANCE,
257 sal_True, sal_True );
258 rExport.IgnorableWhitespace();
259 if( xDoc.is() )
260 {
261 exportDom( rExport, xDoc );
262 }
263 }
264
265
266 //
267 // the binding
268 //
269
270 static const ExportTable aXFormsBindingTable[] =
271 {
272 TABLE_ENTRY( "BindingID", NONE, ID, lcl_string ),
273 TABLE_ENTRY( "BindingExpression", NONE, NODESET, lcl_string ),
274 TABLE_ENTRY( "ReadonlyExpression", NONE, READONLY, lcl_string ),
275 TABLE_ENTRY( "RelevantExpression", NONE, RELEVANT, lcl_string ),
276 TABLE_ENTRY( "RequiredExpression", NONE, REQUIRED, lcl_string ),
277 TABLE_ENTRY( "ConstraintExpression", NONE, CONSTRAINT, lcl_string ),
278 TABLE_ENTRY( "CalculateExpression", NONE, CALCULATE, lcl_string ),
279 // type handled separatly, for type name <-> XSD type conversion
280 // TABLE_ENTRY( "Type", NONE, TYPE, lcl_string ),
281 TABLE_END
282 };
283
exportXFormsBinding(SvXMLExport & rExport,const Reference<XPropertySet> & xBinding)284 void exportXFormsBinding( SvXMLExport& rExport,
285 const Reference<XPropertySet>& xBinding )
286 {
287 // name check; generate binding ID if necessary
288 {
289 OUString sName;
290 xBinding->getPropertyValue( OUSTRING("BindingID") ) >>= sName;
291 if( sName.getLength() == 0 )
292 {
293 // if we don't have a name yet, generate one on the fly
294 OUStringBuffer aBuffer;
295 aBuffer.append( OUSTRING("bind_" ) );
296 sal_Int64 nId = reinterpret_cast<sal_uInt64>( xBinding.get() );
297 aBuffer.append( nId , 16 );
298 sName = aBuffer.makeStringAndClear();
299 xBinding->setPropertyValue( OUSTRING("BindingID"), makeAny(sName));
300 }
301 }
302
303 lcl_export( xBinding, rExport, aXFormsBindingTable );
304
305 // handle type attribute
306 {
307 OUString sTypeName;
308 xBinding->getPropertyValue( OUSTRING("Type") ) >>= sTypeName;
309
310 try
311 {
312 // now get type, and determine whether its a standard type. If
313 // so, export the XSD name
314 Reference<com::sun::star::xforms::XModel> xModel(
315 xBinding->getPropertyValue( OUSTRING("Model") ),
316 UNO_QUERY );
317 Reference<XDataTypeRepository> xRepository(
318 xModel.is() ? xModel->getDataTypeRepository() : Reference<XDataTypeRepository>() );
319 if( xRepository.is() )
320 {
321 Reference<XPropertySet> xDataType(
322 xRepository->getDataType( sTypeName ),
323 UNO_QUERY );
324
325 // if it's a basic data type, write out the XSD name
326 // for the XSD type class
327 bool bIsBasic = false;
328 xDataType->getPropertyValue( OUSTRING("IsBasic") ) >>= bIsBasic;
329 if( bIsBasic )
330 sTypeName = lcl_getXSDType( rExport, xDataType );
331 }
332 }
333 catch( Exception& )
334 {
335 ; // ignore; just use typename
336 }
337
338 // now that we have the proper type name, write out the attribute
339 if( sTypeName.getLength() > 0 )
340 {
341 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_TYPE,
342 sTypeName );
343 }
344 }
345
346 // we need to ensure all the namespaces in the binding will work correctly.
347 // to do so, we will write out all missing namespace declaractions.
348 const SvXMLNamespaceMap& rMap = rExport.GetNamespaceMap();
349 Reference<XNameAccess> xNamespaces(
350 xBinding->getPropertyValue( OUSTRING("ModelNamespaces") ), UNO_QUERY);
351 if( xNamespaces.is() )
352 {
353 // iterate over Prefixes for this binding
354 Sequence<OUString> aPrefixes = xNamespaces->getElementNames();
355 const OUString* pPrefixes = aPrefixes.getConstArray();
356 sal_Int32 nPrefixes = aPrefixes.getLength();
357 for( sal_Int32 i = 0; i < nPrefixes; i++ )
358 {
359 const OUString& rPrefix = pPrefixes[i];
360 OUString sURI;
361 xNamespaces->getByName( rPrefix ) >>= sURI;
362
363 // check whether prefix/URI pair is in map; else write declaration
364 // (we don't need to change the map, since this element has no
365 // other content)
366 sal_uInt16 nKey = rMap.GetKeyByPrefix( rPrefix );
367 if( nKey == XML_NAMESPACE_UNKNOWN ||
368 rMap.GetNameByKey( nKey ) != sURI )
369 {
370 rExport.AddAttribute( OUSTRING("xmlns:") + rPrefix, sURI );
371 }
372 }
373 }
374
375 SvXMLElementExport aElement( rExport, XML_NAMESPACE_XFORMS, XML_BIND,
376 sal_True, sal_True );
377 }
378
379
380 //
381 // the submission
382 //
383
384 static const ExportTable aXFormsSubmissionTable[] =
385 {
386 TABLE_ENTRY( "ID", NONE, ID, lcl_string ),
387 TABLE_ENTRY( "Bind", NONE, BIND, lcl_string ),
388 TABLE_ENTRY( "Ref", NONE, REF, lcl_string ),
389 TABLE_ENTRY( "Action", NONE, ACTION, lcl_string ),
390 TABLE_ENTRY( "Method", NONE, METHOD, lcl_string ),
391 TABLE_ENTRY( "Version", NONE, VERSION, lcl_string ),
392 TABLE_ENTRY( "Indent", NONE, INDENT, lcl_bool ),
393 TABLE_ENTRY( "MediaType", NONE, MEDIATYPE, lcl_string ),
394 TABLE_ENTRY( "Encoding", NONE, ENCODING, lcl_string ),
395 TABLE_ENTRY( "OmitXmlDeclaration", NONE, OMIT_XML_DECLARATION, lcl_bool ),
396 TABLE_ENTRY( "Standalone", NONE, STANDALONE, lcl_bool ),
397 TABLE_ENTRY( "CDataSectionElement", NONE, CDATA_SECTION_ELEMENTS, lcl_string ),
398 TABLE_ENTRY( "Replace", NONE, REPLACE, lcl_string ),
399 TABLE_ENTRY( "Separator", NONE, SEPARATOR, lcl_string ),
400 TABLE_ENTRY( "IncludeNamespacePrefixes", NONE, INCLUDENAMESPACEPREFIXES, lcl_string ),
401 TABLE_END
402 };
403
exportXFormsSubmission(SvXMLExport & rExport,const Reference<XPropertySet> & xSubmission)404 void exportXFormsSubmission( SvXMLExport& rExport,
405 const Reference<XPropertySet>& xSubmission )
406 {
407 lcl_export( xSubmission, rExport, aXFormsSubmissionTable );
408 SvXMLElementExport aElement( rExport, XML_NAMESPACE_XFORMS, XML_SUBMISSION,
409 sal_True, sal_True );
410 }
411
412
413
414 //
415 // export data types as XSD schema
416 //
417
418 static const ExportTable aDataTypeFacetTable[] =
419 {
420 TABLE_ENTRY( "Length", XSD, LENGTH, lcl_int32 ),
421 TABLE_ENTRY( "MinLength", XSD, MINLENGTH, lcl_int32 ),
422 TABLE_ENTRY( "MaxLength", XSD, MAXLENGTH, lcl_int32 ),
423 TABLE_ENTRY( "MinInclusiveInt", XSD, MININCLUSIVE, lcl_int32 ),
424 TABLE_ENTRY( "MinExclusiveInt", XSD, MINEXCLUSIVE, lcl_int32 ),
425 TABLE_ENTRY( "MaxInclusiveInt", XSD, MAXINCLUSIVE, lcl_int32 ),
426 TABLE_ENTRY( "MaxExclusiveInt", XSD, MAXEXCLUSIVE, lcl_int32 ),
427 TABLE_ENTRY( "MinInclusiveDouble", XSD, MININCLUSIVE, lcl_double ),
428 TABLE_ENTRY( "MinExclusiveDouble", XSD, MINEXCLUSIVE, lcl_double ),
429 TABLE_ENTRY( "MaxInclusiveDouble", XSD, MAXINCLUSIVE, lcl_double ),
430 TABLE_ENTRY( "MaxExclusiveDouble", XSD, MAXEXCLUSIVE, lcl_double ),
431 TABLE_ENTRY( "MinInclusiveDate", XSD, MININCLUSIVE, lcl_date ),
432 TABLE_ENTRY( "MinExclusiveDate", XSD, MINEXCLUSIVE, lcl_date ),
433 TABLE_ENTRY( "MaxInclusiveDate", XSD, MAXINCLUSIVE, lcl_date ),
434 TABLE_ENTRY( "MaxExclusiveDate", XSD, MAXEXCLUSIVE, lcl_date ),
435 TABLE_ENTRY( "MinInclusiveTime", XSD, MININCLUSIVE, lcl_time ),
436 TABLE_ENTRY( "MinExclusiveTime", XSD, MINEXCLUSIVE, lcl_time ),
437 TABLE_ENTRY( "MaxInclusiveTime", XSD, MAXINCLUSIVE, lcl_time ),
438 TABLE_ENTRY( "MaxExclusiveTime", XSD, MAXEXCLUSIVE, lcl_time ),
439 TABLE_ENTRY( "MinInclusiveDateTime", XSD, MININCLUSIVE, lcl_dateTime ),
440 TABLE_ENTRY( "MinExclusiveDateTime", XSD, MINEXCLUSIVE, lcl_dateTime ),
441 TABLE_ENTRY( "MaxInclusiveDateTime", XSD, MAXINCLUSIVE, lcl_dateTime ),
442 TABLE_ENTRY( "MaxExclusiveDateTime", XSD, MAXEXCLUSIVE, lcl_dateTime ),
443 TABLE_ENTRY( "Pattern", XSD, PATTERN, lcl_string ),
444 // ??? XML_ENUMERATION,
445 TABLE_ENTRY( "WhiteSpace", XSD, WHITESPACE, lcl_whitespace ),
446 TABLE_ENTRY( "TotalDigits", XSD, TOTALDIGITS, lcl_int32 ),
447 TABLE_ENTRY( "FractionDigits", XSD, FRACTIONDIGITS, lcl_int32 ),
448 TABLE_END
449 };
450
451 // export facets through table; use the same table as lcl_export does
lcl_exportDataTypeFacets(SvXMLExport & rExport,const Reference<XPropertySet> & rPropertySet,const ExportTable * pTable)452 void lcl_exportDataTypeFacets( SvXMLExport& rExport,
453 const Reference<XPropertySet>& rPropertySet,
454 const ExportTable* pTable )
455 {
456 Reference<XPropertySetInfo> xInfo = rPropertySet->getPropertySetInfo();
457 for( const ExportTable* pCurrent = pTable;
458 pCurrent->pPropertyName != NULL;
459 pCurrent++ )
460 {
461 OUString sName( OUString::createFromAscii( pCurrent->pPropertyName ) );
462 if( xInfo->hasPropertyByName( sName ) )
463 {
464 OUString sValue = (*pCurrent->aConverter)(
465 rPropertySet->getPropertyValue( sName ) );
466
467 if( sValue.getLength() > 0 )
468 {
469 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_VALUE, sValue );
470 SvXMLElementExport aFacet(
471 rExport,
472 pCurrent->nNamespace,
473 static_cast<XMLTokenEnum>( pCurrent->nToken ),
474 sal_True, sal_True );
475 }
476 }
477 }
478 }
479
lcl_getXSDType(SvXMLExport & rExport,const Reference<XPropertySet> & xType)480 OUString lcl_getXSDType( SvXMLExport& rExport,
481 const Reference<XPropertySet>& xType )
482 {
483 // we use string as default...
484 XMLTokenEnum eToken = XML_STRING;
485
486 sal_uInt16 nDataTypeClass = 0;
487 xType->getPropertyValue( OUSTRING("TypeClass") ) >>= nDataTypeClass;
488 switch( nDataTypeClass )
489 {
490 case com::sun::star::xsd::DataTypeClass::STRING:
491 eToken = XML_STRING;
492 break;
493 case com::sun::star::xsd::DataTypeClass::anyURI:
494 eToken = XML_ANYURI;
495 break;
496 case com::sun::star::xsd::DataTypeClass::DECIMAL:
497 eToken = XML_DECIMAL;
498 break;
499 case com::sun::star::xsd::DataTypeClass::DOUBLE:
500 eToken = XML_DOUBLE;
501 break;
502 case com::sun::star::xsd::DataTypeClass::FLOAT:
503 eToken = XML_FLOAT;
504 break;
505 case com::sun::star::xsd::DataTypeClass::BOOLEAN:
506 eToken = XML_BOOLEAN;
507 break;
508 case com::sun::star::xsd::DataTypeClass::DATETIME:
509 eToken = XML_DATETIME_XSD;
510 break;
511 case com::sun::star::xsd::DataTypeClass::TIME:
512 eToken = XML_TIME;
513 break;
514 case com::sun::star::xsd::DataTypeClass::DATE:
515 eToken = XML_DATE;
516 break;
517 case com::sun::star::xsd::DataTypeClass::gYear:
518 eToken = XML_YEAR;
519 break;
520 case com::sun::star::xsd::DataTypeClass::gDay:
521 eToken = XML_DAY;
522 break;
523 case com::sun::star::xsd::DataTypeClass::gMonth:
524 eToken = XML_MONTH;
525 break;
526 case com::sun::star::xsd::DataTypeClass::DURATION:
527 case com::sun::star::xsd::DataTypeClass::gYearMonth:
528 case com::sun::star::xsd::DataTypeClass::gMonthDay:
529 case com::sun::star::xsd::DataTypeClass::hexBinary:
530 case com::sun::star::xsd::DataTypeClass::base64Binary:
531 case com::sun::star::xsd::DataTypeClass::QName:
532 case com::sun::star::xsd::DataTypeClass::NOTATION:
533 default:
534 DBG_ERROR( "unknown data type" );
535 }
536
537 return rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_XSD,
538 GetXMLToken( eToken ) );
539 }
540
lcl_exportDataType(SvXMLExport & rExport,const Reference<XPropertySet> & xType)541 void lcl_exportDataType( SvXMLExport& rExport,
542 const Reference<XPropertySet>& xType )
543 {
544 // we do not need to export basic types; exit if we have one
545 bool bIsBasic = false;
546 xType->getPropertyValue( OUSTRING("IsBasic") ) >>= bIsBasic;
547 if( bIsBasic )
548 return;
549
550 // no basic type -> export
551
552 // <xsd:simpleType name="...">
553 OUString sName;
554 xType->getPropertyValue( OUSTRING("Name") ) >>= sName;
555 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_NAME, sName );
556 SvXMLElementExport aSimpleType( rExport,
557 XML_NAMESPACE_XSD, XML_SIMPLETYPE,
558 sal_True, sal_True );
559
560 // <xsd:restriction base="xsd:...">
561 rExport.AddAttribute( XML_NAMESPACE_NONE, XML_BASE,
562 lcl_getXSDType( rExport, xType ) );
563 SvXMLElementExport aRestriction( rExport,
564 XML_NAMESPACE_XSD,
565 XML_RESTRICTION,
566 sal_True, sal_True );
567
568 // export facets
569 lcl_exportDataTypeFacets( rExport,
570 Reference<XPropertySet>( xType, UNO_QUERY ),
571 aDataTypeFacetTable );
572 }
573
exportXFormsSchemas(SvXMLExport & rExport,const Reference<com::sun::star::xforms::XModel> & xModel)574 void exportXFormsSchemas( SvXMLExport& rExport,
575 const Reference<com::sun::star::xforms::XModel>& xModel )
576 {
577 // TODO: for now, we'll fake this...
578 {
579 SvXMLElementExport aSchemaElem( rExport, XML_NAMESPACE_XSD, XML_SCHEMA,
580 sal_True, sal_True );
581
582 // now get data type repositry, and export
583 Reference<XEnumerationAccess> xTypes( xModel->getDataTypeRepository(),
584 UNO_QUERY );
585 if( xTypes.is() )
586 {
587 Reference<XEnumeration> xEnum = xTypes->createEnumeration();
588 DBG_ASSERT( xEnum.is(), "no enum?" );
589 while( xEnum->hasMoreElements() )
590 {
591 Reference<XPropertySet> xType( xEnum->nextElement(), UNO_QUERY );
592 lcl_exportDataType( rExport, xType );
593 }
594 }
595 }
596
597 // export other, 'foreign' schemas
598 Reference<XPropertySet> xPropSet( xModel, UNO_QUERY );
599 if( xPropSet.is() )
600 {
601 Reference<XDocument> xDocument(
602 xPropSet->getPropertyValue( OUSTRING("ForeignSchema") ),
603 UNO_QUERY );
604
605 if( xDocument.is() )
606 exportDom( rExport, xDocument );
607 }
608 }
609
610
611
612 //
613 // helper functions
614 //
615
lcl_export(const Reference<XPropertySet> & rPropertySet,SvXMLExport & rExport,const ExportTable * pTable)616 void lcl_export( const Reference<XPropertySet>& rPropertySet,
617 SvXMLExport& rExport,
618 const ExportTable* pTable )
619 {
620 for( const ExportTable* pCurrent = pTable;
621 pCurrent->pPropertyName != NULL;
622 pCurrent++ )
623 {
624 Any aAny = rPropertySet->getPropertyValue(
625 OUString::createFromAscii( pCurrent->pPropertyName ) );
626 OUString sValue = (*pCurrent->aConverter)( aAny );
627
628 if( sValue.getLength() > 0 )
629 rExport.AddAttribute(
630 pCurrent->nNamespace,
631 static_cast<XMLTokenEnum>( pCurrent->nToken ),
632 sValue );
633 }
634 }
635
636
637
638 //
639 // any conversion functions
640 //
641
642 template<typename T, void (*FUNC)( OUStringBuffer&, T )>
lcl_convert(const Any & rAny)643 OUString lcl_convert( const Any& rAny )
644 {
645 OUStringBuffer aBuffer;
646 T aData = T();
647 if( rAny >>= aData )
648 {
649 FUNC( aBuffer, aData );
650 }
651 return aBuffer.makeStringAndClear();
652 }
653
654 template<typename T, void (*FUNC)( OUStringBuffer&, const T& )>
lcl_convertRef(const Any & rAny)655 OUString lcl_convertRef( const Any& rAny )
656 {
657 OUStringBuffer aBuffer;
658 T aData;
659 if( rAny >>= aData )
660 {
661 FUNC( aBuffer, aData );
662 }
663 return aBuffer.makeStringAndClear();
664 }
665
lcl_string(const Any & rAny)666 OUString lcl_string( const Any& rAny )
667 {
668 OUString aResult;
669 rAny >>= aResult;
670 return aResult;
671 }
672
lcl_bool(const Any & rAny)673 OUString lcl_bool( const Any& rAny )
674 {
675 bool bResult = bool();
676 if( rAny >>= bResult )
677 return GetXMLToken( bResult ? XML_TRUE : XML_FALSE );
678 DBG_ERROR( "expected boolean value" );
679 return OUString();
680 }
681
lcl_formatDate(OUStringBuffer & aBuffer,const Date & rDate)682 void lcl_formatDate( OUStringBuffer& aBuffer, const Date& rDate )
683 {
684 aBuffer.append( static_cast<sal_Int32>( rDate.Year ) );
685 aBuffer.append( sal_Unicode('-') );
686 aBuffer.append( static_cast<sal_Int32>( rDate.Month ) );
687 aBuffer.append( sal_Unicode('-') );
688 aBuffer.append( static_cast<sal_Int32>( rDate.Day ) );
689 }
690
lcl_formatTime(OUStringBuffer & aBuffer,const com::sun::star::util::Time & rTime)691 void lcl_formatTime( OUStringBuffer& aBuffer, const com::sun::star::util::Time& rTime )
692 {
693 DateTime aDateTime;
694 aDateTime.Hours = rTime.Hours;
695 aDateTime.Minutes = rTime.Minutes;
696 aDateTime.Seconds = rTime.Seconds;
697 aDateTime.HundredthSeconds = rTime.HundredthSeconds;
698 SvXMLUnitConverter::convertTime( aBuffer, aDateTime );
699 }
700
lcl_formatDateTime(OUStringBuffer & aBuffer,const DateTime & aDateTime)701 void lcl_formatDateTime( OUStringBuffer& aBuffer, const DateTime& aDateTime )
702 {
703 SvXMLUnitConverter::convertDateTime( aBuffer, aDateTime );
704 }
705
lcl_whitespace(const Any & rAny)706 OUString lcl_whitespace( const Any& rAny )
707 {
708 OUString sResult;
709 sal_uInt16 n = sal_uInt16();
710 if( rAny >>= n )
711 {
712 switch( n )
713 {
714 case com::sun::star::xsd::WhiteSpaceTreatment::Preserve:
715 sResult = GetXMLToken( XML_PRESERVE );
716 break;
717 case com::sun::star::xsd::WhiteSpaceTreatment::Replace:
718 sResult = GetXMLToken( XML_REPLACE );
719 break;
720 case com::sun::star::xsd::WhiteSpaceTreatment::Collapse:
721 sResult = GetXMLToken( XML_COLLAPSE );
722 break;
723 }
724 }
725 return sResult;
726 }
727
728
729 /// return name of Binding
lcl_getXFormsBindName(const Reference<XPropertySet> & xBinding)730 OUString lcl_getXFormsBindName( const Reference<XPropertySet>& xBinding )
731 {
732 OUString sProp( OUSTRING( "BindingID" ) );
733
734 OUString sReturn;
735 if( xBinding.is() &&
736 xBinding->getPropertySetInfo()->hasPropertyByName( sProp ) )
737 {
738 xBinding->getPropertyValue( sProp ) >>= sReturn;
739 }
740 return sReturn;
741 }
742
743 // return name of binding
getXFormsBindName(const Reference<XPropertySet> & xControl)744 OUString getXFormsBindName( const Reference<XPropertySet>& xControl )
745 {
746 Reference<XBindableValue> xBindable( xControl, UNO_QUERY );
747 return xBindable.is()
748 ? lcl_getXFormsBindName(
749 Reference<XPropertySet>( xBindable->getValueBinding(), UNO_QUERY ))
750 : OUString();
751 }
752
753 // return name of list binding
getXFormsListBindName(const Reference<XPropertySet> & xControl)754 OUString getXFormsListBindName( const Reference<XPropertySet>& xControl )
755 {
756 Reference<XListEntrySink> xListEntrySink( xControl, UNO_QUERY );
757 return xListEntrySink.is()
758 ? lcl_getXFormsBindName(
759 Reference<XPropertySet>( xListEntrySink->getListEntrySource(),
760 UNO_QUERY ) )
761 : OUString();
762 }
763
getXFormsSubmissionName(const Reference<XPropertySet> & xBinding)764 OUString getXFormsSubmissionName( const Reference<XPropertySet>& xBinding )
765 {
766 OUString sReturn;
767
768 Reference<XSubmissionSupplier> xSubmissionSupplier( xBinding, UNO_QUERY );
769 if( xSubmissionSupplier.is() )
770 {
771 Reference<XPropertySet> xPropertySet(
772 xSubmissionSupplier->getSubmission(), UNO_QUERY );
773 OUString sProp( OUSTRING("ID") );
774 if( xPropertySet.is() &&
775 xPropertySet->getPropertySetInfo()->hasPropertyByName( sProp ) )
776 {
777 xPropertySet->getPropertyValue( sProp ) >>= sReturn;
778 }
779 }
780
781 return sReturn;
782 }
783
getXFormsSettings(const Reference<XNameAccess> & _rXForms,Sequence<PropertyValue> & _out_rSettings)784 void getXFormsSettings( const Reference< XNameAccess >& _rXForms, Sequence< PropertyValue >& _out_rSettings )
785 {
786 _out_rSettings = Sequence< PropertyValue >();
787
788 OSL_PRECOND( _rXForms.is(), "getXFormsSettings: invalid XForms container!" );
789 if ( !_rXForms.is() )
790 return;
791
792 try
793 {
794 // we want to export some special properties of our XForms models as config-item-map-named,
795 // which implies we need a PropertyValue whose value is an XNameAccess, whose keys
796 // are the names of the XForm models, and which in turn provides named sequences of
797 // PropertyValues - which denote the actual property values of the given named model.
798
799 Sequence< ::rtl::OUString > aModelNames( _rXForms->getElementNames() );
800
801 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
802 Reference< XNameContainer > xModelSettings(
803 aContext.createComponent( "com.sun.star.document.NamedPropertyValues" ),
804 UNO_QUERY_THROW );
805
806 for ( const ::rtl::OUString* pModelName = aModelNames.getConstArray();
807 pModelName != aModelNames.getConstArray() + aModelNames.getLength();
808 ++pModelName
809 )
810 {
811 Reference< XPropertySet > xModelProps( _rXForms->getByName( *pModelName ), UNO_QUERY_THROW );
812
813 Sequence< PropertyValue > aModelSettings( 1 );
814 aModelSettings[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExternalData" ) );
815 aModelSettings[0].Value = xModelProps->getPropertyValue( aModelSettings[0].Name );
816
817 xModelSettings->insertByName( *pModelName, makeAny( aModelSettings ) );
818 }
819
820 if ( xModelSettings->hasElements() )
821 {
822 _out_rSettings.realloc( 1 );
823 _out_rSettings[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XFormModels" ) );
824 _out_rSettings[0].Value <<= xModelSettings;
825 }
826 }
827 catch( const Exception& )
828 {
829 DBG_UNHANDLED_EXCEPTION();
830 }
831 }
832