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 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 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 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 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 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 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 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 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 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 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 )> 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& )> 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 666 OUString lcl_string( const Any& rAny ) 667 { 668 OUString aResult; 669 rAny >>= aResult; 670 return aResult; 671 } 672 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 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 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 701 void lcl_formatDateTime( OUStringBuffer& aBuffer, const DateTime& aDateTime ) 702 { 703 SvXMLUnitConverter::convertDateTime( aBuffer, aDateTime ); 704 } 705 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 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 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 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 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 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