| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| |
| #include "xmloff/xformsexport.hxx" |
| |
| #include "XFormsModelExport.hxx" |
| #include "xformsapi.hxx" |
| |
| #include <xmloff/xmlexp.hxx> |
| #include <xmloff/xmltoken.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/nmspmap.hxx> |
| #include "DomExport.hxx" |
| #include <xmloff/xmluconv.hxx> |
| #include <comphelper/componentcontext.hxx> |
| #include <comphelper/processfactory.hxx> |
| |
| #include "tools/debug.hxx" |
| #include <tools/diagnose_ex.h> |
| #include <com/sun/star/container/XIndexAccess.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/xml/dom/XDocument.hpp> |
| #include <com/sun/star/form/binding/XValueBinding.hpp> |
| #include <com/sun/star/form/binding/XBindableValue.hpp> |
| #include <com/sun/star/form/binding/XListEntrySink.hpp> |
| #include <com/sun/star/form/binding/XListEntrySource.hpp> |
| #include <com/sun/star/form/submission/XSubmissionSupplier.hpp> |
| #include <com/sun/star/xforms/XModel.hpp> |
| #include <com/sun/star/xforms/XDataTypeRepository.hpp> |
| #include <com/sun/star/xforms/XFormsSupplier.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/container/XEnumerationAccess.hpp> |
| #include <com/sun/star/container/XEnumeration.hpp> |
| #include <com/sun/star/container/XNameContainer.hpp> |
| #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> |
| #include <com/sun/star/xsd/DataTypeClass.hpp> |
| #include <com/sun/star/xsd/XDataType.hpp> |
| #include <com/sun/star/util/Date.hpp> |
| #include <com/sun/star/util/Time.hpp> |
| #include <com/sun/star/util/DateTime.hpp> |
| |
| using namespace com::sun::star; |
| using namespace com::sun::star::uno; |
| using namespace xmloff::token; |
| |
| using rtl::OUString; |
| using rtl::OUStringBuffer; |
| using com::sun::star::beans::XPropertySet; |
| using com::sun::star::beans::XPropertySetInfo; |
| using com::sun::star::container::XIndexAccess; |
| using com::sun::star::container::XNameAccess; |
| using com::sun::star::container::XNameContainer; |
| using com::sun::star::container::XEnumerationAccess; |
| using com::sun::star::container::XEnumeration; |
| using com::sun::star::xml::dom::XDocument; |
| using com::sun::star::form::binding::XValueBinding; |
| using com::sun::star::form::binding::XBindableValue; |
| using com::sun::star::form::binding::XListEntrySink; |
| using com::sun::star::form::submission::XSubmissionSupplier; |
| using com::sun::star::beans::PropertyValue; |
| using com::sun::star::xsd::XDataType; |
| using com::sun::star::xforms::XDataTypeRepository; |
| using com::sun::star::xforms::XFormsSupplier; |
| using com::sun::star::util::Date; |
| using com::sun::star::util::DateTime; |
| |
| void exportXForms( SvXMLExport& rExport ) |
| { |
| Reference<XFormsSupplier> xSupplier( rExport.GetModel(), UNO_QUERY ); |
| if( xSupplier.is() ) |
| { |
| Reference<XNameContainer> xForms = xSupplier->getXForms(); |
| if( xForms.is() ) |
| { |
| Sequence<OUString> aNames = xForms->getElementNames(); |
| const OUString* pNames = aNames.getConstArray(); |
| sal_Int32 nNames = aNames.getLength(); |
| |
| for( sal_Int32 n = 0; n < nNames; n++ ) |
| { |
| Reference<XPropertySet> xModel( xForms->getByName( pNames[n] ), |
| UNO_QUERY ); |
| exportXFormsModel( rExport, xModel ); |
| } |
| } |
| } |
| } |
| |
| |
| void exportXFormsInstance( SvXMLExport&, const Sequence<PropertyValue>& ); |
| void exportXFormsBinding( SvXMLExport&, const Reference<XPropertySet>& ); |
| void exportXFormsSubmission( SvXMLExport&, const Reference<XPropertySet>& ); |
| void exportXFormsSchemas( SvXMLExport&, const Reference<com::sun::star::xforms::XModel>& ); |
| |
| |
| typedef OUString (*convert_t)( const Any& ); |
| typedef struct |
| { |
| const sal_Char* pPropertyName; |
| sal_uInt16 nPropertyNameLength; |
| sal_uInt16 nNamespace; |
| sal_uInt16 nToken; |
| convert_t aConverter; |
| } ExportTable; |
| void lcl_export( const Reference<XPropertySet>& rPropertySet, |
| SvXMLExport& rExport, |
| const ExportTable* pTable ); |
| |
| #define TABLE_ENTRY(NAME,NAMESPACE,TOKEN,CONVERTER) { NAME,sizeof(NAME)-1,XML_NAMESPACE_##NAMESPACE,xmloff::token::XML_##TOKEN, CONVERTER } |
| #define TABLE_END { NULL, 0, 0, 0, NULL } |
| |
| |
| // any conversion functions |
| OUString lcl_string( const Any& ); |
| OUString lcl_bool( const Any& ); |
| OUString lcl_whitespace( const Any& ); |
| template<typename T, void (*FUNC)( OUStringBuffer&, T )> OUString lcl_convert( const Any& ); |
| template<typename T, void (*FUNC)( OUStringBuffer&, const T& )> OUString lcl_convertRef( const Any& ); |
| |
| void lcl_formatDate( OUStringBuffer& aBuffer, const Date& aDate ); |
| void lcl_formatTime( OUStringBuffer& aBuffer, const com::sun::star::util::Time& aTime ); |
| void lcl_formatDateTime( OUStringBuffer& aBuffer, const DateTime& aDateTime ); |
| |
| convert_t lcl_int32 = &lcl_convert<sal_Int32,&SvXMLUnitConverter::convertNumber>; |
| convert_t lcl_double = &lcl_convert<double,&SvXMLUnitConverter::convertDouble>; |
| convert_t lcl_dateTime = &lcl_convertRef<DateTime,&lcl_formatDateTime>; |
| convert_t lcl_date = &lcl_convertRef<Date,&lcl_formatDate>; |
| convert_t lcl_time = &lcl_convertRef<com::sun::star::util::Time,&lcl_formatTime>; |
| |
| // other functions |
| OUString lcl_getXSDType( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xType ); |
| |
| |
| // |
| // the model |
| // |
| |
| static const ExportTable aXFormsModelTable[] = |
| { |
| TABLE_ENTRY( "ID", NONE, ID, lcl_string ), |
| TABLE_ENTRY( "SchemaRef", NONE, SCHEMA, lcl_string ), |
| TABLE_END |
| }; |
| |
| void exportXFormsModel( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xModelPropSet ) |
| { |
| // no model -> don't do anything! |
| Reference<com::sun::star::xforms::XModel> xModel( xModelPropSet, UNO_QUERY ); |
| if( ! xModel.is() || ! xModelPropSet.is() ) |
| return; |
| |
| lcl_export( xModelPropSet, rExport, aXFormsModelTable ); |
| SvXMLElementExport aModelElement( rExport, XML_NAMESPACE_XFORMS, XML_MODEL, |
| sal_True, sal_True ); |
| |
| // instances |
| Reference<XIndexAccess> xInstances( xModel->getInstances(), |
| UNO_QUERY_THROW); |
| sal_Int32 nCount = xInstances->getCount(); |
| sal_Int32 i = 0; |
| for( i = 0; i < nCount; i++ ) |
| { |
| Sequence<PropertyValue> aInstance; |
| xInstances->getByIndex( i ) >>= aInstance; |
| exportXFormsInstance( rExport, aInstance ); |
| } |
| |
| |
| // bindings |
| Reference<XIndexAccess> xBindings( xModel->getBindings(), UNO_QUERY_THROW); |
| nCount = xBindings->getCount(); |
| for( i = 0; i < nCount; i++ ) |
| { |
| Reference<XPropertySet> aBinding( xBindings->getByIndex( i ), |
| UNO_QUERY_THROW ); |
| exportXFormsBinding( rExport, aBinding ); |
| } |
| |
| // submissions |
| Reference<XIndexAccess> xSubmissions( xModel->getSubmissions(), |
| UNO_QUERY_THROW ); |
| nCount = xSubmissions->getCount(); |
| for( i = 0; i < nCount; i++ ) |
| { |
| Reference<XPropertySet> xSubmission( xSubmissions->getByIndex( i ), |
| UNO_QUERY_THROW ); |
| exportXFormsSubmission( rExport, xSubmission ); |
| } |
| |
| // schemas |
| exportXFormsSchemas( rExport, xModel ); |
| } |
| |
| // |
| // the instance |
| // |
| |
| static const ExportTable aXFormsInstanceTable[] = |
| { |
| TABLE_ENTRY( "InstanceURL", NONE, SRC, lcl_string ), |
| TABLE_END |
| }; |
| |
| void exportXFormsInstance( SvXMLExport& rExport, |
| const Sequence<PropertyValue>& xInstance ) |
| { |
| OUString sId; |
| OUString sURL; |
| Reference<XDocument> xDoc; |
| |
| const PropertyValue* pInstance = xInstance.getConstArray(); |
| sal_Int32 nCount = xInstance.getLength(); |
| for( sal_Int32 i = 0; i < nCount; i++ ) |
| { |
| OUString sName = pInstance[i].Name; |
| const Any& rAny = pInstance[i].Value; |
| if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ID") ) ) |
| rAny >>= sId; |
| else if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("URL") ) ) |
| rAny >>= sURL; |
| else if( sName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Instance") )) |
| rAny >>= xDoc; |
| } |
| |
| if( sId.getLength() > 0 ) |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_ID, sId ); |
| |
| if( sURL.getLength() > 0 ) |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_SRC, sURL ); |
| |
| SvXMLElementExport aElem( rExport, XML_NAMESPACE_XFORMS, XML_INSTANCE, |
| sal_True, sal_True ); |
| rExport.IgnorableWhitespace(); |
| if( xDoc.is() ) |
| { |
| exportDom( rExport, xDoc ); |
| } |
| } |
| |
| |
| // |
| // the binding |
| // |
| |
| static const ExportTable aXFormsBindingTable[] = |
| { |
| TABLE_ENTRY( "BindingID", NONE, ID, lcl_string ), |
| TABLE_ENTRY( "BindingExpression", NONE, NODESET, lcl_string ), |
| TABLE_ENTRY( "ReadonlyExpression", NONE, READONLY, lcl_string ), |
| TABLE_ENTRY( "RelevantExpression", NONE, RELEVANT, lcl_string ), |
| TABLE_ENTRY( "RequiredExpression", NONE, REQUIRED, lcl_string ), |
| TABLE_ENTRY( "ConstraintExpression", NONE, CONSTRAINT, lcl_string ), |
| TABLE_ENTRY( "CalculateExpression", NONE, CALCULATE, lcl_string ), |
| // type handled separatly, for type name <-> XSD type conversion |
| // TABLE_ENTRY( "Type", NONE, TYPE, lcl_string ), |
| TABLE_END |
| }; |
| |
| void exportXFormsBinding( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xBinding ) |
| { |
| // name check; generate binding ID if necessary |
| { |
| OUString sName; |
| xBinding->getPropertyValue( OUSTRING("BindingID") ) >>= sName; |
| if( sName.getLength() == 0 ) |
| { |
| // if we don't have a name yet, generate one on the fly |
| OUStringBuffer aBuffer; |
| aBuffer.append( OUSTRING("bind_" ) ); |
| sal_Int64 nId = reinterpret_cast<sal_uInt64>( xBinding.get() ); |
| aBuffer.append( nId , 16 ); |
| sName = aBuffer.makeStringAndClear(); |
| xBinding->setPropertyValue( OUSTRING("BindingID"), makeAny(sName)); |
| } |
| } |
| |
| lcl_export( xBinding, rExport, aXFormsBindingTable ); |
| |
| // handle type attribute |
| { |
| OUString sTypeName; |
| xBinding->getPropertyValue( OUSTRING("Type") ) >>= sTypeName; |
| |
| try |
| { |
| // now get type, and determine whether its a standard type. If |
| // so, export the XSD name |
| Reference<com::sun::star::xforms::XModel> xModel( |
| xBinding->getPropertyValue( OUSTRING("Model") ), |
| UNO_QUERY ); |
| Reference<XDataTypeRepository> xRepository( |
| xModel.is() ? xModel->getDataTypeRepository() : Reference<XDataTypeRepository>() ); |
| if( xRepository.is() ) |
| { |
| Reference<XPropertySet> xDataType( |
| xRepository->getDataType( sTypeName ), |
| UNO_QUERY ); |
| |
| // if it's a basic data type, write out the XSD name |
| // for the XSD type class |
| bool bIsBasic = false; |
| xDataType->getPropertyValue( OUSTRING("IsBasic") ) >>= bIsBasic; |
| if( bIsBasic ) |
| sTypeName = lcl_getXSDType( rExport, xDataType ); |
| } |
| } |
| catch( Exception& ) |
| { |
| ; // ignore; just use typename |
| } |
| |
| // now that we have the proper type name, write out the attribute |
| if( sTypeName.getLength() > 0 ) |
| { |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_TYPE, |
| sTypeName ); |
| } |
| } |
| |
| // we need to ensure all the namespaces in the binding will work correctly. |
| // to do so, we will write out all missing namespace declaractions. |
| const SvXMLNamespaceMap& rMap = rExport.GetNamespaceMap(); |
| Reference<XNameAccess> xNamespaces( |
| xBinding->getPropertyValue( OUSTRING("ModelNamespaces") ), UNO_QUERY); |
| if( xNamespaces.is() ) |
| { |
| // iterate over Prefixes for this binding |
| Sequence<OUString> aPrefixes = xNamespaces->getElementNames(); |
| const OUString* pPrefixes = aPrefixes.getConstArray(); |
| sal_Int32 nPrefixes = aPrefixes.getLength(); |
| for( sal_Int32 i = 0; i < nPrefixes; i++ ) |
| { |
| const OUString& rPrefix = pPrefixes[i]; |
| OUString sURI; |
| xNamespaces->getByName( rPrefix ) >>= sURI; |
| |
| // check whether prefix/URI pair is in map; else write declaration |
| // (we don't need to change the map, since this element has no |
| // other content) |
| sal_uInt16 nKey = rMap.GetKeyByPrefix( rPrefix ); |
| if( nKey == XML_NAMESPACE_UNKNOWN || |
| rMap.GetNameByKey( nKey ) != sURI ) |
| { |
| rExport.AddAttribute( OUSTRING("xmlns:") + rPrefix, sURI ); |
| } |
| } |
| } |
| |
| SvXMLElementExport aElement( rExport, XML_NAMESPACE_XFORMS, XML_BIND, |
| sal_True, sal_True ); |
| } |
| |
| |
| // |
| // the submission |
| // |
| |
| static const ExportTable aXFormsSubmissionTable[] = |
| { |
| TABLE_ENTRY( "ID", NONE, ID, lcl_string ), |
| TABLE_ENTRY( "Bind", NONE, BIND, lcl_string ), |
| TABLE_ENTRY( "Ref", NONE, REF, lcl_string ), |
| TABLE_ENTRY( "Action", NONE, ACTION, lcl_string ), |
| TABLE_ENTRY( "Method", NONE, METHOD, lcl_string ), |
| TABLE_ENTRY( "Version", NONE, VERSION, lcl_string ), |
| TABLE_ENTRY( "Indent", NONE, INDENT, lcl_bool ), |
| TABLE_ENTRY( "MediaType", NONE, MEDIATYPE, lcl_string ), |
| TABLE_ENTRY( "Encoding", NONE, ENCODING, lcl_string ), |
| TABLE_ENTRY( "OmitXmlDeclaration", NONE, OMIT_XML_DECLARATION, lcl_bool ), |
| TABLE_ENTRY( "Standalone", NONE, STANDALONE, lcl_bool ), |
| TABLE_ENTRY( "CDataSectionElement", NONE, CDATA_SECTION_ELEMENTS, lcl_string ), |
| TABLE_ENTRY( "Replace", NONE, REPLACE, lcl_string ), |
| TABLE_ENTRY( "Separator", NONE, SEPARATOR, lcl_string ), |
| TABLE_ENTRY( "IncludeNamespacePrefixes", NONE, INCLUDENAMESPACEPREFIXES, lcl_string ), |
| TABLE_END |
| }; |
| |
| void exportXFormsSubmission( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xSubmission ) |
| { |
| lcl_export( xSubmission, rExport, aXFormsSubmissionTable ); |
| SvXMLElementExport aElement( rExport, XML_NAMESPACE_XFORMS, XML_SUBMISSION, |
| sal_True, sal_True ); |
| } |
| |
| |
| |
| // |
| // export data types as XSD schema |
| // |
| |
| static const ExportTable aDataTypeFacetTable[] = |
| { |
| TABLE_ENTRY( "Length", XSD, LENGTH, lcl_int32 ), |
| TABLE_ENTRY( "MinLength", XSD, MINLENGTH, lcl_int32 ), |
| TABLE_ENTRY( "MaxLength", XSD, MAXLENGTH, lcl_int32 ), |
| TABLE_ENTRY( "MinInclusiveInt", XSD, MININCLUSIVE, lcl_int32 ), |
| TABLE_ENTRY( "MinExclusiveInt", XSD, MINEXCLUSIVE, lcl_int32 ), |
| TABLE_ENTRY( "MaxInclusiveInt", XSD, MAXINCLUSIVE, lcl_int32 ), |
| TABLE_ENTRY( "MaxExclusiveInt", XSD, MAXEXCLUSIVE, lcl_int32 ), |
| TABLE_ENTRY( "MinInclusiveDouble", XSD, MININCLUSIVE, lcl_double ), |
| TABLE_ENTRY( "MinExclusiveDouble", XSD, MINEXCLUSIVE, lcl_double ), |
| TABLE_ENTRY( "MaxInclusiveDouble", XSD, MAXINCLUSIVE, lcl_double ), |
| TABLE_ENTRY( "MaxExclusiveDouble", XSD, MAXEXCLUSIVE, lcl_double ), |
| TABLE_ENTRY( "MinInclusiveDate", XSD, MININCLUSIVE, lcl_date ), |
| TABLE_ENTRY( "MinExclusiveDate", XSD, MINEXCLUSIVE, lcl_date ), |
| TABLE_ENTRY( "MaxInclusiveDate", XSD, MAXINCLUSIVE, lcl_date ), |
| TABLE_ENTRY( "MaxExclusiveDate", XSD, MAXEXCLUSIVE, lcl_date ), |
| TABLE_ENTRY( "MinInclusiveTime", XSD, MININCLUSIVE, lcl_time ), |
| TABLE_ENTRY( "MinExclusiveTime", XSD, MINEXCLUSIVE, lcl_time ), |
| TABLE_ENTRY( "MaxInclusiveTime", XSD, MAXINCLUSIVE, lcl_time ), |
| TABLE_ENTRY( "MaxExclusiveTime", XSD, MAXEXCLUSIVE, lcl_time ), |
| TABLE_ENTRY( "MinInclusiveDateTime", XSD, MININCLUSIVE, lcl_dateTime ), |
| TABLE_ENTRY( "MinExclusiveDateTime", XSD, MINEXCLUSIVE, lcl_dateTime ), |
| TABLE_ENTRY( "MaxInclusiveDateTime", XSD, MAXINCLUSIVE, lcl_dateTime ), |
| TABLE_ENTRY( "MaxExclusiveDateTime", XSD, MAXEXCLUSIVE, lcl_dateTime ), |
| TABLE_ENTRY( "Pattern", XSD, PATTERN, lcl_string ), |
| // ??? XML_ENUMERATION, |
| TABLE_ENTRY( "WhiteSpace", XSD, WHITESPACE, lcl_whitespace ), |
| TABLE_ENTRY( "TotalDigits", XSD, TOTALDIGITS, lcl_int32 ), |
| TABLE_ENTRY( "FractionDigits", XSD, FRACTIONDIGITS, lcl_int32 ), |
| TABLE_END |
| }; |
| |
| // export facets through table; use the same table as lcl_export does |
| void lcl_exportDataTypeFacets( SvXMLExport& rExport, |
| const Reference<XPropertySet>& rPropertySet, |
| const ExportTable* pTable ) |
| { |
| Reference<XPropertySetInfo> xInfo = rPropertySet->getPropertySetInfo(); |
| for( const ExportTable* pCurrent = pTable; |
| pCurrent->pPropertyName != NULL; |
| pCurrent++ ) |
| { |
| OUString sName( OUString::createFromAscii( pCurrent->pPropertyName ) ); |
| if( xInfo->hasPropertyByName( sName ) ) |
| { |
| OUString sValue = (*pCurrent->aConverter)( |
| rPropertySet->getPropertyValue( sName ) ); |
| |
| if( sValue.getLength() > 0 ) |
| { |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_VALUE, sValue ); |
| SvXMLElementExport aFacet( |
| rExport, |
| pCurrent->nNamespace, |
| static_cast<XMLTokenEnum>( pCurrent->nToken ), |
| sal_True, sal_True ); |
| } |
| } |
| } |
| } |
| |
| OUString lcl_getXSDType( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xType ) |
| { |
| // we use string as default... |
| XMLTokenEnum eToken = XML_STRING; |
| |
| sal_uInt16 nDataTypeClass = 0; |
| xType->getPropertyValue( OUSTRING("TypeClass") ) >>= nDataTypeClass; |
| switch( nDataTypeClass ) |
| { |
| case com::sun::star::xsd::DataTypeClass::STRING: |
| eToken = XML_STRING; |
| break; |
| case com::sun::star::xsd::DataTypeClass::anyURI: |
| eToken = XML_ANYURI; |
| break; |
| case com::sun::star::xsd::DataTypeClass::DECIMAL: |
| eToken = XML_DECIMAL; |
| break; |
| case com::sun::star::xsd::DataTypeClass::DOUBLE: |
| eToken = XML_DOUBLE; |
| break; |
| case com::sun::star::xsd::DataTypeClass::FLOAT: |
| eToken = XML_FLOAT; |
| break; |
| case com::sun::star::xsd::DataTypeClass::BOOLEAN: |
| eToken = XML_BOOLEAN; |
| break; |
| case com::sun::star::xsd::DataTypeClass::DATETIME: |
| eToken = XML_DATETIME_XSD; |
| break; |
| case com::sun::star::xsd::DataTypeClass::TIME: |
| eToken = XML_TIME; |
| break; |
| case com::sun::star::xsd::DataTypeClass::DATE: |
| eToken = XML_DATE; |
| break; |
| case com::sun::star::xsd::DataTypeClass::gYear: |
| eToken = XML_YEAR; |
| break; |
| case com::sun::star::xsd::DataTypeClass::gDay: |
| eToken = XML_DAY; |
| break; |
| case com::sun::star::xsd::DataTypeClass::gMonth: |
| eToken = XML_MONTH; |
| break; |
| case com::sun::star::xsd::DataTypeClass::DURATION: |
| case com::sun::star::xsd::DataTypeClass::gYearMonth: |
| case com::sun::star::xsd::DataTypeClass::gMonthDay: |
| case com::sun::star::xsd::DataTypeClass::hexBinary: |
| case com::sun::star::xsd::DataTypeClass::base64Binary: |
| case com::sun::star::xsd::DataTypeClass::QName: |
| case com::sun::star::xsd::DataTypeClass::NOTATION: |
| default: |
| DBG_ERROR( "unknown data type" ); |
| } |
| |
| return rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_XSD, |
| GetXMLToken( eToken ) ); |
| } |
| |
| void lcl_exportDataType( SvXMLExport& rExport, |
| const Reference<XPropertySet>& xType ) |
| { |
| // we do not need to export basic types; exit if we have one |
| bool bIsBasic = false; |
| xType->getPropertyValue( OUSTRING("IsBasic") ) >>= bIsBasic; |
| if( bIsBasic ) |
| return; |
| |
| // no basic type -> export |
| |
| // <xsd:simpleType name="..."> |
| OUString sName; |
| xType->getPropertyValue( OUSTRING("Name") ) >>= sName; |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_NAME, sName ); |
| SvXMLElementExport aSimpleType( rExport, |
| XML_NAMESPACE_XSD, XML_SIMPLETYPE, |
| sal_True, sal_True ); |
| |
| // <xsd:restriction base="xsd:..."> |
| rExport.AddAttribute( XML_NAMESPACE_NONE, XML_BASE, |
| lcl_getXSDType( rExport, xType ) ); |
| SvXMLElementExport aRestriction( rExport, |
| XML_NAMESPACE_XSD, |
| XML_RESTRICTION, |
| sal_True, sal_True ); |
| |
| // export facets |
| lcl_exportDataTypeFacets( rExport, |
| Reference<XPropertySet>( xType, UNO_QUERY ), |
| aDataTypeFacetTable ); |
| } |
| |
| void exportXFormsSchemas( SvXMLExport& rExport, |
| const Reference<com::sun::star::xforms::XModel>& xModel ) |
| { |
| // TODO: for now, we'll fake this... |
| { |
| SvXMLElementExport aSchemaElem( rExport, XML_NAMESPACE_XSD, XML_SCHEMA, |
| sal_True, sal_True ); |
| |
| // now get data type repositry, and export |
| Reference<XEnumerationAccess> xTypes( xModel->getDataTypeRepository(), |
| UNO_QUERY ); |
| if( xTypes.is() ) |
| { |
| Reference<XEnumeration> xEnum = xTypes->createEnumeration(); |
| DBG_ASSERT( xEnum.is(), "no enum?" ); |
| while( xEnum->hasMoreElements() ) |
| { |
| Reference<XPropertySet> xType( xEnum->nextElement(), UNO_QUERY ); |
| lcl_exportDataType( rExport, xType ); |
| } |
| } |
| } |
| |
| // export other, 'foreign' schemas |
| Reference<XPropertySet> xPropSet( xModel, UNO_QUERY ); |
| if( xPropSet.is() ) |
| { |
| Reference<XDocument> xDocument( |
| xPropSet->getPropertyValue( OUSTRING("ForeignSchema") ), |
| UNO_QUERY ); |
| |
| if( xDocument.is() ) |
| exportDom( rExport, xDocument ); |
| } |
| } |
| |
| |
| |
| // |
| // helper functions |
| // |
| |
| void lcl_export( const Reference<XPropertySet>& rPropertySet, |
| SvXMLExport& rExport, |
| const ExportTable* pTable ) |
| { |
| for( const ExportTable* pCurrent = pTable; |
| pCurrent->pPropertyName != NULL; |
| pCurrent++ ) |
| { |
| Any aAny = rPropertySet->getPropertyValue( |
| OUString::createFromAscii( pCurrent->pPropertyName ) ); |
| OUString sValue = (*pCurrent->aConverter)( aAny ); |
| |
| if( sValue.getLength() > 0 ) |
| rExport.AddAttribute( |
| pCurrent->nNamespace, |
| static_cast<XMLTokenEnum>( pCurrent->nToken ), |
| sValue ); |
| } |
| } |
| |
| |
| |
| // |
| // any conversion functions |
| // |
| |
| template<typename T, void (*FUNC)( OUStringBuffer&, T )> |
| OUString lcl_convert( const Any& rAny ) |
| { |
| OUStringBuffer aBuffer; |
| T aData = T(); |
| if( rAny >>= aData ) |
| { |
| FUNC( aBuffer, aData ); |
| } |
| return aBuffer.makeStringAndClear(); |
| } |
| |
| template<typename T, void (*FUNC)( OUStringBuffer&, const T& )> |
| OUString lcl_convertRef( const Any& rAny ) |
| { |
| OUStringBuffer aBuffer; |
| T aData; |
| if( rAny >>= aData ) |
| { |
| FUNC( aBuffer, aData ); |
| } |
| return aBuffer.makeStringAndClear(); |
| } |
| |
| OUString lcl_string( const Any& rAny ) |
| { |
| OUString aResult; |
| rAny >>= aResult; |
| return aResult; |
| } |
| |
| OUString lcl_bool( const Any& rAny ) |
| { |
| bool bResult = bool(); |
| if( rAny >>= bResult ) |
| return GetXMLToken( bResult ? XML_TRUE : XML_FALSE ); |
| DBG_ERROR( "expected boolean value" ); |
| return OUString(); |
| } |
| |
| void lcl_formatDate( OUStringBuffer& aBuffer, const Date& rDate ) |
| { |
| aBuffer.append( static_cast<sal_Int32>( rDate.Year ) ); |
| aBuffer.append( sal_Unicode('-') ); |
| aBuffer.append( static_cast<sal_Int32>( rDate.Month ) ); |
| aBuffer.append( sal_Unicode('-') ); |
| aBuffer.append( static_cast<sal_Int32>( rDate.Day ) ); |
| } |
| |
| void lcl_formatTime( OUStringBuffer& aBuffer, const com::sun::star::util::Time& rTime ) |
| { |
| DateTime aDateTime; |
| aDateTime.Hours = rTime.Hours; |
| aDateTime.Minutes = rTime.Minutes; |
| aDateTime.Seconds = rTime.Seconds; |
| aDateTime.HundredthSeconds = rTime.HundredthSeconds; |
| SvXMLUnitConverter::convertTime( aBuffer, aDateTime ); |
| } |
| |
| void lcl_formatDateTime( OUStringBuffer& aBuffer, const DateTime& aDateTime ) |
| { |
| SvXMLUnitConverter::convertDateTime( aBuffer, aDateTime ); |
| } |
| |
| OUString lcl_whitespace( const Any& rAny ) |
| { |
| OUString sResult; |
| sal_uInt16 n = sal_uInt16(); |
| if( rAny >>= n ) |
| { |
| switch( n ) |
| { |
| case com::sun::star::xsd::WhiteSpaceTreatment::Preserve: |
| sResult = GetXMLToken( XML_PRESERVE ); |
| break; |
| case com::sun::star::xsd::WhiteSpaceTreatment::Replace: |
| sResult = GetXMLToken( XML_REPLACE ); |
| break; |
| case com::sun::star::xsd::WhiteSpaceTreatment::Collapse: |
| sResult = GetXMLToken( XML_COLLAPSE ); |
| break; |
| } |
| } |
| return sResult; |
| } |
| |
| |
| /// return name of Binding |
| OUString lcl_getXFormsBindName( const Reference<XPropertySet>& xBinding ) |
| { |
| OUString sProp( OUSTRING( "BindingID" ) ); |
| |
| OUString sReturn; |
| if( xBinding.is() && |
| xBinding->getPropertySetInfo()->hasPropertyByName( sProp ) ) |
| { |
| xBinding->getPropertyValue( sProp ) >>= sReturn; |
| } |
| return sReturn; |
| } |
| |
| // return name of binding |
| OUString getXFormsBindName( const Reference<XPropertySet>& xControl ) |
| { |
| Reference<XBindableValue> xBindable( xControl, UNO_QUERY ); |
| return xBindable.is() |
| ? lcl_getXFormsBindName( |
| Reference<XPropertySet>( xBindable->getValueBinding(), UNO_QUERY )) |
| : OUString(); |
| } |
| |
| // return name of list binding |
| OUString getXFormsListBindName( const Reference<XPropertySet>& xControl ) |
| { |
| Reference<XListEntrySink> xListEntrySink( xControl, UNO_QUERY ); |
| return xListEntrySink.is() |
| ? lcl_getXFormsBindName( |
| Reference<XPropertySet>( xListEntrySink->getListEntrySource(), |
| UNO_QUERY ) ) |
| : OUString(); |
| } |
| |
| OUString getXFormsSubmissionName( const Reference<XPropertySet>& xBinding ) |
| { |
| OUString sReturn; |
| |
| Reference<XSubmissionSupplier> xSubmissionSupplier( xBinding, UNO_QUERY ); |
| if( xSubmissionSupplier.is() ) |
| { |
| Reference<XPropertySet> xPropertySet( |
| xSubmissionSupplier->getSubmission(), UNO_QUERY ); |
| OUString sProp( OUSTRING("ID") ); |
| if( xPropertySet.is() && |
| xPropertySet->getPropertySetInfo()->hasPropertyByName( sProp ) ) |
| { |
| xPropertySet->getPropertyValue( sProp ) >>= sReturn; |
| } |
| } |
| |
| return sReturn; |
| } |
| |
| void getXFormsSettings( const Reference< XNameAccess >& _rXForms, Sequence< PropertyValue >& _out_rSettings ) |
| { |
| _out_rSettings = Sequence< PropertyValue >(); |
| |
| OSL_PRECOND( _rXForms.is(), "getXFormsSettings: invalid XForms container!" ); |
| if ( !_rXForms.is() ) |
| return; |
| |
| try |
| { |
| // we want to export some special properties of our XForms models as config-item-map-named, |
| // which implies we need a PropertyValue whose value is an XNameAccess, whose keys |
| // are the names of the XForm models, and which in turn provides named sequences of |
| // PropertyValues - which denote the actual property values of the given named model. |
| |
| Sequence< ::rtl::OUString > aModelNames( _rXForms->getElementNames() ); |
| |
| ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); |
| Reference< XNameContainer > xModelSettings( |
| aContext.createComponent( "com.sun.star.document.NamedPropertyValues" ), |
| UNO_QUERY_THROW ); |
| |
| for ( const ::rtl::OUString* pModelName = aModelNames.getConstArray(); |
| pModelName != aModelNames.getConstArray() + aModelNames.getLength(); |
| ++pModelName |
| ) |
| { |
| Reference< XPropertySet > xModelProps( _rXForms->getByName( *pModelName ), UNO_QUERY_THROW ); |
| |
| Sequence< PropertyValue > aModelSettings( 1 ); |
| aModelSettings[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExternalData" ) ); |
| aModelSettings[0].Value = xModelProps->getPropertyValue( aModelSettings[0].Name ); |
| |
| xModelSettings->insertByName( *pModelName, makeAny( aModelSettings ) ); |
| } |
| |
| if ( xModelSettings->hasElements() ) |
| { |
| _out_rSettings.realloc( 1 ); |
| _out_rSettings[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XFormModels" ) ); |
| _out_rSettings[0].Value <<= xModelSettings; |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |