diff options
Diffstat (limited to 'xmloff/source/xforms')
21 files changed, 3688 insertions, 0 deletions
diff --git a/xmloff/source/xforms/SchemaContext.cxx b/xmloff/source/xforms/SchemaContext.cxx new file mode 100644 index 000000000000..14f12bc5df69 --- /dev/null +++ b/xmloff/source/xforms/SchemaContext.cxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "SchemaContext.hxx" + +#include "SchemaSimpleTypeContext.hxx" + +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmluconv.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> +#include <com/sun/star/xforms/XDataTypeRepository.hpp> + +#include <tools/debug.hxx> + + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Any; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::xforms::XDataTypeRepository; +using namespace xmloff::token; + + + + +static SvXMLTokenMapEntry aAttributes[] = +{ + XML_TOKEN_MAP_END +}; + +static SvXMLTokenMapEntry aChildren[] = +{ + TOKEN_MAP_ENTRY( XSD, SIMPLETYPE ), + XML_TOKEN_MAP_END +}; + + +SchemaContext::SchemaContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XDataTypeRepository>& rRepository ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ), + mxRepository( rRepository ) +{ +} + +SchemaContext::~SchemaContext() +{ +} + +void SchemaContext::HandleAttribute( + sal_uInt16, + const OUString& ) +{ +} + +SvXMLImportContext* SchemaContext::HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& ) +{ + return ( nToken == XML_SIMPLETYPE ) + ? new SchemaSimpleTypeContext( GetImport(), nPrefix, rLocalName, + mxRepository ) + : new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} diff --git a/xmloff/source/xforms/SchemaContext.hxx b/xmloff/source/xforms/SchemaContext.hxx new file mode 100644 index 000000000000..e3a0be34c29f --- /dev/null +++ b/xmloff/source/xforms/SchemaContext.hxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_SCHEMACONTEXT_HXX +#define _XMLOFF_SCHEMACONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } + namespace xforms { class XDataTypeRepository; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + +/** import the data type declarations from an xsd:schema element */ +class SchemaContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository> mxRepository; + +public: + + SchemaContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository ); + virtual ~SchemaContext(); + + + // + // implement TokenContext methods: + // + +protected: + + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); +}; + +#endif diff --git a/xmloff/source/xforms/SchemaRestrictionContext.cxx b/xmloff/source/xforms/SchemaRestrictionContext.cxx new file mode 100644 index 000000000000..0663aa2531f4 --- /dev/null +++ b/xmloff/source/xforms/SchemaRestrictionContext.cxx @@ -0,0 +1,380 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "SchemaRestrictionContext.hxx" +#include "xformsapi.hxx" + +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlimp.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Type.hxx> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Time.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/xforms/XDataTypeRepository.hpp> +#include <com/sun/star/xsd/DataTypeClass.hpp> +#include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> + +#include <tools/debug.hxx> + + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::Any; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::util::Date; +using com::sun::star::util::DateTime; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::xforms::XDataTypeRepository; +using namespace xmloff::token; + + + + +static SvXMLTokenMapEntry aAttributes[] = +{ + TOKEN_MAP_ENTRY( NONE, BASE ), + XML_TOKEN_MAP_END +}; + +static SvXMLTokenMapEntry aChildren[] = +{ + TOKEN_MAP_ENTRY( XSD, LENGTH ), + TOKEN_MAP_ENTRY( XSD, MINLENGTH ), + TOKEN_MAP_ENTRY( XSD, MAXLENGTH ), + TOKEN_MAP_ENTRY( XSD, MININCLUSIVE ), + TOKEN_MAP_ENTRY( XSD, MINEXCLUSIVE ), + TOKEN_MAP_ENTRY( XSD, MAXINCLUSIVE ), + TOKEN_MAP_ENTRY( XSD, MAXEXCLUSIVE ), + TOKEN_MAP_ENTRY( XSD, PATTERN ), + // ??? XML_ENUMERATION + TOKEN_MAP_ENTRY( XSD, WHITESPACE ), + TOKEN_MAP_ENTRY( XSD, TOTALDIGITS ), + TOKEN_MAP_ENTRY( XSD, FRACTIONDIGITS ), + XML_TOKEN_MAP_END +}; + + +SchemaRestrictionContext::SchemaRestrictionContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository, + const OUString& sTypeName ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ), + mxRepository( rRepository ), + msTypeName( sTypeName ), + msBaseName() +{ + DBG_ASSERT( mxRepository.is(), "need repository" ); +} + +SchemaRestrictionContext::~SchemaRestrictionContext() +{ +} + +void SchemaRestrictionContext::CreateDataType() +{ + // only do something if we don't have a data type already + if( mxDataType.is() ) + return; + + DBG_ASSERT( msBaseName.getLength() > 0, "no base name?" ); + DBG_ASSERT( mxRepository.is(), "no repository?" ); + + try + { + mxDataType = + Reference<XPropertySet>( + mxRepository->cloneDataType( + lcl_getBasicTypeName( mxRepository, + GetImport().GetNamespaceMap(), + msBaseName ), + msTypeName ), + UNO_QUERY ); + } + catch( const Exception& ) + { + DBG_ERROR( "exception during type creation" ); + } + DBG_ASSERT( mxDataType.is(), "can't create type" ); +} + +void SchemaRestrictionContext::HandleAttribute( + sal_uInt16 nToken, + const OUString& rValue ) +{ + if( nToken == XML_BASE ) + { + msBaseName = rValue; + } +} + +typedef Any (*convert_t)( const OUString& ); + +Any lcl_string( const OUString& rValue ) +{ + return makeAny( rValue ); +} + +Any lcl_int32( const OUString& rValue ) +{ + sal_Int32 nValue; + bool bSuccess = SvXMLUnitConverter::convertNumber( nValue, rValue ); + return bSuccess ? makeAny( nValue ) : Any(); +} + +Any lcl_int16( const OUString& rValue ) +{ + sal_Int32 nValue; + bool bSuccess = SvXMLUnitConverter::convertNumber( nValue, rValue ); + return bSuccess ? makeAny( static_cast<sal_Int16>( nValue ) ) : Any(); +} + +Any lcl_whitespace( const OUString& rValue ) +{ + Any aValue; + if( IsXMLToken( rValue, XML_PRESERVE ) ) + aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Preserve; + else if( IsXMLToken( rValue, XML_REPLACE ) ) + aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Replace; + else if( IsXMLToken( rValue, XML_COLLAPSE ) ) + aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Collapse; + return aValue; +} + +Any lcl_double( const OUString& rValue ) +{ + double fValue; + bool bSuccess = SvXMLUnitConverter::convertDouble( fValue, rValue ); + return bSuccess ? makeAny( fValue ) : Any(); +} + +Any lcl_date( const OUString& rValue ) +{ + Any aAny; + + // parse ISO date + sal_Int32 nPos1 = rValue.indexOf( sal_Unicode('-') ); + sal_Int32 nPos2 = rValue.indexOf( sal_Unicode('-'), nPos1 + 1 ); + if( nPos1 > 0 && nPos2 > 0 ) + { + Date aDate; + aDate.Year = static_cast<sal_uInt16>( + rValue.copy( 0, nPos1 ).toInt32() ); + aDate.Month = static_cast<sal_uInt16>( + rValue.copy( nPos1 + 1, nPos2 - nPos1 - 1 ).toInt32() ); + aDate.Day = static_cast<sal_uInt16>( + rValue.copy( nPos2 + 1 ).toInt32() ); + aAny <<= aDate; + } + return aAny; +} + +Any lcl_dateTime( const OUString& rValue ) +{ + DateTime aDateTime; + bool bSuccess = SvXMLUnitConverter::convertDateTime( aDateTime, rValue ); + return bSuccess ? makeAny( aDateTime ) : Any(); +} + +Any lcl_time( const OUString& rValue ) +{ + Any aAny; + DateTime aDateTime; + if( SvXMLUnitConverter::convertTime( aDateTime, rValue ) ) + { + com::sun::star::util::Time aTime; + aTime.Hours = aDateTime.Hours; + aTime.Minutes = aDateTime.Minutes; + aTime.Seconds = aDateTime.Seconds; + aTime.HundredthSeconds = aDateTime.HundredthSeconds; + aAny <<= aTime; + } + return aAny; +} + + +SvXMLImportContext* SchemaRestrictionContext::HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& xAttrList ) +{ + // find value + OUString sValue; + sal_Int16 nLength = xAttrList->getLength(); + for( sal_Int16 n = 0; n < nLength; n++ ) + { + if( IsXMLToken( xAttrList->getNameByIndex( n ), XML_VALUE ) ) + sValue = xAttrList->getValueByIndex( n ); + } + + // determine property name + suitable converter + OUString sPropertyName; + convert_t pConvert = NULL; + switch( nToken ) + { + case XML_LENGTH: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("Length")); + pConvert = &lcl_int32; + break; + case XML_MINLENGTH: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinLength")); + pConvert = &lcl_int32; + break; + case XML_MAXLENGTH: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxLength")); + pConvert = &lcl_int32; + break; + case XML_TOTALDIGITS: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("TotalDigits")); + pConvert = &lcl_int32; + break; + case XML_FRACTIONDIGITS: + sPropertyName =OUString(RTL_CONSTASCII_USTRINGPARAM("FractionDigits")); + pConvert = &lcl_int32; + break; + case XML_PATTERN: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("Pattern")); + pConvert = &lcl_string; + break; + case XML_WHITESPACE: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("WhiteSpace")); + pConvert = &lcl_whitespace; + break; + case XML_MININCLUSIVE: + case XML_MINEXCLUSIVE: + case XML_MAXINCLUSIVE: + case XML_MAXEXCLUSIVE: + { + // these attributes are mapped to different properties. + // To determine the property name, we use an attribute + // dependent prefix and a type dependent suffix. The + // converter is only type dependent. + + // first, attribute-dependent prefix + switch( nToken ) + { + case XML_MININCLUSIVE: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinInclusive")); + break; + case XML_MINEXCLUSIVE: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinExclusive")); + break; + case XML_MAXINCLUSIVE: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxInclusive")); + break; + case XML_MAXEXCLUSIVE: + sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxExclusive")); + break; + } + + // second, type-dependent suffix + converter + switch( lcl_getTypeClass( mxRepository, + GetImport().GetNamespaceMap(), + msBaseName ) ) + { + case com::sun::star::xsd::DataTypeClass::DECIMAL: + case com::sun::star::xsd::DataTypeClass::DOUBLE: + case com::sun::star::xsd::DataTypeClass::FLOAT: + sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Double")); + pConvert = &lcl_double; + break; + case com::sun::star::xsd::DataTypeClass::DATETIME: + sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("DateTime")); + pConvert = &lcl_dateTime; + break; + case com::sun::star::xsd::DataTypeClass::DATE: + sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Date")); + pConvert = &lcl_date; + break; + case com::sun::star::xsd::DataTypeClass::TIME: + sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Time")); + pConvert = &lcl_time; + break; + case com::sun::star::xsd::DataTypeClass::gYear: + case com::sun::star::xsd::DataTypeClass::gDay: + case com::sun::star::xsd::DataTypeClass::gMonth: + sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Int")); + pConvert = &lcl_int16; + break; + + case com::sun::star::xsd::DataTypeClass::STRING: + case com::sun::star::xsd::DataTypeClass::anyURI: + case com::sun::star::xsd::DataTypeClass::BOOLEAN: + // invalid: These shouldn't have min/max-inclusive + break; + + /* data types not yet supported: + 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: + */ + } + } + break; + + default: + DBG_ERROR( "unknown facet" ); + } + + // finally, set the property + CreateDataType(); + if( mxDataType.is() + && sPropertyName.getLength() > 0 + && pConvert != NULL + && mxDataType->getPropertySetInfo()->hasPropertyByName(sPropertyName) ) + { + try + { + mxDataType->setPropertyValue( sPropertyName, pConvert( sValue ) ); + } + catch( const Exception& ) + { + ; // can't set property? Then ignore. + } + } + + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} diff --git a/xmloff/source/xforms/SchemaRestrictionContext.hxx b/xmloff/source/xforms/SchemaRestrictionContext.hxx new file mode 100644 index 000000000000..c08251aadbbe --- /dev/null +++ b/xmloff/source/xforms/SchemaRestrictionContext.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_SCHEMARESTRICTIONCONTEXT_HXX +#define _XMLOFF_SCHEMARESTRICTIONCONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } + namespace xforms { class XDataTypeRepository; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + +/** import the xsd:restriction element */ +class SchemaRestrictionContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository> mxRepository; + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> mxDataType; + ::rtl::OUString msTypeName; + ::rtl::OUString msBaseName; + +public: + + SchemaRestrictionContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository, + const ::rtl::OUString& sTypeName ); + virtual ~SchemaRestrictionContext(); + + +protected: + + // create mxDataType (if not already present) + void CreateDataType(); + + // + // implement TokenContext methods: + // + + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); +}; + +#endif diff --git a/xmloff/source/xforms/SchemaSimpleTypeContext.cxx b/xmloff/source/xforms/SchemaSimpleTypeContext.cxx new file mode 100644 index 000000000000..821dd768fbf9 --- /dev/null +++ b/xmloff/source/xforms/SchemaSimpleTypeContext.cxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "SchemaSimpleTypeContext.hxx" + +#include "SchemaRestrictionContext.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmluconv.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> + +#include <tools/debug.hxx> + + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Any; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::beans::XPropertySet; +using com::sun::star::xforms::XDataTypeRepository; +using namespace xmloff::token; + + + + +static SvXMLTokenMapEntry aAttributes[] = +{ + TOKEN_MAP_ENTRY( NONE, NAME ), + XML_TOKEN_MAP_END +}; + +static SvXMLTokenMapEntry aChildren[] = +{ + TOKEN_MAP_ENTRY( XSD, RESTRICTION ), + XML_TOKEN_MAP_END +}; + + +SchemaSimpleTypeContext::SchemaSimpleTypeContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XDataTypeRepository>& rRepository ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ), + mxRepository( rRepository ) +{ +} + +SchemaSimpleTypeContext::~SchemaSimpleTypeContext() +{ +} + +void SchemaSimpleTypeContext::HandleAttribute( + sal_uInt16 nToken, + const OUString& rValue ) +{ + if( nToken == XML_NAME ) + { + msTypeName = rValue; + } +} + +SvXMLImportContext* SchemaSimpleTypeContext::HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& ) +{ + SvXMLImportContext* pContext = NULL; + switch( nToken ) + { + case XML_RESTRICTION: + pContext = new SchemaRestrictionContext( GetImport(), + nPrefix, rLocalName, + mxRepository, msTypeName ); + break; + default: + DBG_ERROR( "Booo!" ); + } + + return ( pContext != NULL ) + ? pContext + : new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} diff --git a/xmloff/source/xforms/SchemaSimpleTypeContext.hxx b/xmloff/source/xforms/SchemaSimpleTypeContext.hxx new file mode 100644 index 000000000000..cf4221f7168c --- /dev/null +++ b/xmloff/source/xforms/SchemaSimpleTypeContext.hxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_SCHEMASIMPLETYPECONTEXT_HXX +#define _XMLOFF_SCHEMASIMPLETYPECONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } + namespace xforms { class XDataTypeRepository; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + +/** import the xsd:simpleType element */ +class SchemaSimpleTypeContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository> mxRepository; + rtl::OUString msTypeName; + +public: + + SchemaSimpleTypeContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + const com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository ); + + virtual ~SchemaSimpleTypeContext(); + + + // + // implement TokenContext methods: + // + +protected: + + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); +}; + +#endif diff --git a/xmloff/source/xforms/TokenContext.cxx b/xmloff/source/xforms/TokenContext.cxx new file mode 100644 index 000000000000..d1310effeeb8 --- /dev/null +++ b/xmloff/source/xforms/TokenContext.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" +#include "TokenContext.hxx" +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/nmspmap.hxx> +#include "xmloff/xmlerror.hxx" + +#include <tools/debug.hxx> + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::xml::sax::XAttributeList; + + +struct SvXMLTokenMapEntry aEmptyMap[1] = +{ + XML_TOKEN_MAP_END +}; + + +TokenContext::TokenContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const SvXMLTokenMapEntry* pAttributes, + const SvXMLTokenMapEntry* pChildren ) + : SvXMLImportContext( rImport, nPrefix, rLocalName ), + mpAttributes( pAttributes ), + mpChildren( pChildren ) +{ +} + +TokenContext::~TokenContext() +{ +} + +void TokenContext::StartElement( + const Reference<XAttributeList>& xAttributeList ) +{ + // iterate over attributes + // - if in map: call HandleAttribute + // - xmlns:... : ignore + // - other: warning + DBG_ASSERT( mpAttributes != NULL, "no token map for attributes" ); + SvXMLTokenMap aMap( mpAttributes ); + + sal_Int16 nCount = xAttributeList->getLength(); + for( sal_Int16 i = 0; i < nCount; i++ ) + { + // get key/local-name pair from namespace map + OUString sLocalName; + sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). + GetKeyByAttrName( xAttributeList->getNameByIndex(i), &sLocalName ); + + // get token from token map + sal_uInt16 nToken = aMap.Get( nPrefix, sLocalName ); + + // and the value... + const OUString& rValue = xAttributeList->getValueByIndex(i); + + if( nToken != XML_TOK_UNKNOWN ) + { + HandleAttribute( nToken, rValue ); + } + else if( nPrefix != XML_NAMESPACE_XMLNS ) + { + // error handling, for all attribute that are not + // namespace declarations + GetImport().SetError( XMLERROR_UNKNOWN_ATTRIBUTE, + sLocalName, rValue); + } + } +} + +SvXMLImportContext* TokenContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& xAttrList ) +{ + // call HandleChild for elements in token map. Ignore other content. + + SvXMLImportContext* pContext = NULL; + + DBG_ASSERT( mpChildren != NULL, "no token map for child elements" ); + SvXMLTokenMap aMap( mpChildren ); + sal_uInt16 nToken = aMap.Get( nPrefix, rLocalName ); + if( nToken != XML_TOK_UNKNOWN ) + { + // call handle child, and pass down arguments + pContext = HandleChild( nToken, nPrefix, rLocalName, xAttrList ); + } + + // error handling: create default context and generate warning + if( pContext == NULL ) + { + GetImport().SetError( XMLERROR_UNKNOWN_ELEMENT, rLocalName ); + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + } + return pContext; +} + +bool lcl_IsWhiteSpace( sal_Unicode c ) +{ + return c == sal_Unicode( ' ' ) + || c == sal_Unicode( 0x09 ) + || c == sal_Unicode( 0x0A ) + || c == sal_Unicode( 0x0D ); +} + +void TokenContext::Characters( const ::rtl::OUString& rCharacters ) +{ + // get iterators for string data + const sal_Unicode* pBegin = rCharacters.getStr(); + const sal_Unicode* pEnd = &( pBegin[ rCharacters.getLength() ] ); + + // raise error if non-whitespace character is found + if( ::std::find_if( pBegin, pEnd, ::std::not1(::std::ptr_fun(lcl_IsWhiteSpace)) ) != pEnd ) + GetImport().SetError( XMLERROR_UNKNOWN_CHARACTERS, rCharacters ); +} diff --git a/xmloff/source/xforms/TokenContext.hxx b/xmloff/source/xforms/TokenContext.hxx new file mode 100644 index 000000000000..7200eb0891a1 --- /dev/null +++ b/xmloff/source/xforms/TokenContext.hxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_TOKENCONTEXT_HXX +#define _XMLOFF_TOKENCONTEXT_HXX + + +// +// include for parent class and members +// + +#include <xmloff/xmlictxt.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace uno { template<typename T> class Reference; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; + +#define TOKEN_MAP_ENTRY(NAMESPACE,TOKEN) { XML_NAMESPACE_##NAMESPACE, xmloff::token::XML_##TOKEN, xmloff::token::XML_##TOKEN } + +extern struct SvXMLTokenMapEntry aEmptyMap[1]; + +/** handle attributes through an SvXMLTokenMap */ +class TokenContext : public SvXMLImportContext +{ +protected: + const SvXMLTokenMapEntry* mpAttributes; /// static token map + const SvXMLTokenMapEntry* mpChildren; /// static token map + +public: + + TokenContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const ::rtl::OUString& rLocalName, + const SvXMLTokenMapEntry* pAttributes = NULL, + const SvXMLTokenMapEntry* pChildren = NULL ); + + virtual ~TokenContext(); + + + // + // implement SvXMLImportContext methods: + // + + /** call HandleAttribute for each attribute in the token map; + * create a warning for all others. Classes that wish to override + * StartElement need to call the parent method. */ + virtual void StartElement( + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + /** call HandleChild for each child element in the token map; + * create a warning for all others. Classes that wish to override + * CreateChildCotnenxt may want to call the parent method for + * handling of defaults. */ + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + + /** Create a warning for all non-namespace character + * content. Classes that wish to deal with character content have + * to overload this method anyway, and will thus get rid of the + * warnings. */ + virtual void Characters( const ::rtl::OUString& rChars ); + +protected: + /** will be called for each attribute */ + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ) = 0; + + /** will be called for each child element */ + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + + // the following attributes are mainly to be used for child + // context creation + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ) = 0; +}; + +#endif diff --git a/xmloff/source/xforms/XFormsBindContext.cxx b/xmloff/source/xforms/XFormsBindContext.cxx new file mode 100644 index 000000000000..67bbf8f70b84 --- /dev/null +++ b/xmloff/source/xforms/XFormsBindContext.cxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "XFormsBindContext.hxx" + +#include "xformsapi.hxx" + +#include <xmloff/xmlimp.hxx> +#include "xmloff/xmlerror.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmltkmap.hxx> +#include "xmloff/xmlnmspe.hxx" +#include <xmloff/nmspmap.hxx> + +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/xforms/XModel.hpp> + +#include <tools/debug.hxx> + +using rtl::OUString; +using com::sun::star::beans::XPropertySet; +using com::sun::star::uno::Reference; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::UNO_QUERY_THROW; +using com::sun::star::container::XNameContainer; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::xforms::XModel; +using namespace xmloff::token; + + + + +static struct SvXMLTokenMapEntry aAttributeMap[] = +{ + TOKEN_MAP_ENTRY( NONE, NODESET ), + TOKEN_MAP_ENTRY( NONE, ID ), + TOKEN_MAP_ENTRY( NONE, READONLY ), + TOKEN_MAP_ENTRY( NONE, RELEVANT ), + TOKEN_MAP_ENTRY( NONE, REQUIRED ), + TOKEN_MAP_ENTRY( NONE, CONSTRAINT ), + TOKEN_MAP_ENTRY( NONE, CALCULATE ), + TOKEN_MAP_ENTRY( NONE, TYPE ), + XML_TOKEN_MAP_END +}; + +// helper function; see below +void lcl_fillNamespaceContainer( const SvXMLNamespaceMap&, + Reference<XNameContainer>& ); + +XFormsBindContext::XFormsBindContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XPropertySet>& xModel ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributeMap, aEmptyMap ), + mxModel( xModel, UNO_QUERY_THROW ), + mxBinding( NULL ) +{ + // attach binding to model + mxBinding = mxModel->createBinding(); + DBG_ASSERT( mxBinding.is(), "can't create binding" ); + mxModel->getBindings()->insert( makeAny( mxBinding ) ); +} + +XFormsBindContext::~XFormsBindContext() +{ +} + +void XFormsBindContext::HandleAttribute( sal_uInt16 nToken, + const OUString& rValue ) +{ + switch( nToken ) + { + case XML_NODESET: + lcl_setValue( mxBinding, OUSTRING("BindingExpression"), rValue ); + break; + case XML_ID: + lcl_setValue( mxBinding, OUSTRING("BindingID"), rValue ); + break; + case XML_READONLY: + lcl_setValue( mxBinding, OUSTRING("ReadonlyExpression"), rValue ); + break; + case XML_RELEVANT: + lcl_setValue( mxBinding, OUSTRING("RelevantExpression"), rValue ); + break; + case XML_REQUIRED: + lcl_setValue( mxBinding, OUSTRING("RequiredExpression"), rValue ); + break; + case XML_CONSTRAINT: + lcl_setValue( mxBinding, OUSTRING("ConstraintExpression"), rValue ); + break; + case XML_CALCULATE: + lcl_setValue( mxBinding, OUSTRING("CalculateExpression"), rValue ); + break; + case XML_TYPE: + lcl_setValue( mxBinding, OUSTRING("Type"), + makeAny( lcl_getTypeName( mxModel->getDataTypeRepository(), + GetImport().GetNamespaceMap(), + rValue ) ) ); + break; + default: + DBG_ERROR( "should not happen" ); + break; + } +} + +void XFormsBindContext::StartElement( + const Reference<XAttributeList>& xAttributeList ) +{ + // we need to register the namespaces + Reference<XNameContainer> xContainer( + mxBinding->getPropertyValue( OUSTRING("BindingNamespaces") ), + UNO_QUERY ); + + DBG_ASSERT( xContainer.is(), "binding should have a namespace container" ); + if( xContainer.is() ) + lcl_fillNamespaceContainer( GetImport().GetNamespaceMap(), xContainer); + + // call super-class for attribute handling + TokenContext::StartElement( xAttributeList ); +} + +/** will be called for each child element */ +SvXMLImportContext* XFormsBindContext::HandleChild( + sal_uInt16, + sal_uInt16, + const OUString&, + const Reference<XAttributeList>& ) +{ + DBG_ERROR( "no children supported" ); + return NULL; +} + + +void lcl_fillNamespaceContainer( + const SvXMLNamespaceMap& aMap, + Reference<XNameContainer>& xContainer ) +{ + sal_uInt16 nKeyIter = aMap.GetFirstKey(); + do + { + // get prefix and namespace + const OUString& sPrefix = aMap.GetPrefixByKey( nKeyIter ); + const OUString& sNamespace = aMap.GetNameByKey( nKeyIter ); + + // as a hack, we will ignore our own 'default' namespaces + DBG_ASSERT( sPrefix.getLength() > 0, "no prefix?" ); + if( sPrefix.getStr()[0] != sal_Unicode( '_' ) && + nKeyIter >= XML_OLD_NAMESPACE_META_IDX ) + { + // insert prefix (use replace if already known) + if( xContainer->hasByName( sPrefix ) ) + xContainer->replaceByName( sPrefix, makeAny( sNamespace ) ); + else + xContainer->insertByName( sPrefix, makeAny( sNamespace ) ); + } + + // proceed to next + nKeyIter = aMap.GetNextKey( nKeyIter ); + } + while( nKeyIter != XML_NAMESPACE_UNKNOWN ); +} diff --git a/xmloff/source/xforms/XFormsBindContext.hxx b/xmloff/source/xforms/XFormsBindContext.hxx new file mode 100644 index 000000000000..af2d7a440e3a --- /dev/null +++ b/xmloff/source/xforms/XFormsBindContext.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_XFORMSBINDCONTEXT_HXX +#define _XMLOFF_XFORMSBINDCONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } + namespace xforms { class XModel; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + + +/** import the xforms:binding element */ +class XFormsBindContext : public TokenContext +{ + const com::sun::star::uno::Reference<com::sun::star::xforms::XModel> mxModel; + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> mxBinding; + +public: + + XFormsBindContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xModel ); + virtual ~XFormsBindContext(); + + + // + // implement SvXMLImportContext & TokenContext methods: + // + + virtual void StartElement( + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + +protected: + virtual void HandleAttribute( sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nNamespace, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + +}; + +#endif diff --git a/xmloff/source/xforms/XFormsInstanceContext.cxx b/xmloff/source/xforms/XFormsInstanceContext.cxx new file mode 100644 index 000000000000..06cabce7267f --- /dev/null +++ b/xmloff/source/xforms/XFormsInstanceContext.cxx @@ -0,0 +1,158 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "XFormsInstanceContext.hxx" + +#include "DomBuilderContext.hxx" +#include "xformsapi.hxx" + +#include <rtl/ustring.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/xml/dom/XDocument.hpp> +#include <com/sun/star/xforms/XModel.hpp> +#include <tools/debug.hxx> + +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlimp.hxx> +#include <xmloff/xmlerror.hxx> +#include <xmloff/nmspmap.hxx> + + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::Sequence; +using com::sun::star::xforms::XModel; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::PropertyValue; +using com::sun::star::xml::sax::XAttributeList; + +using xmloff::token::IsXMLToken; +using xmloff::token::XML_INSTANCE; +using xmloff::token::XML_SRC; +using xmloff::token::XML_ID; + +static SvXMLTokenMapEntry aAttributes[] = +{ + TOKEN_MAP_ENTRY( NONE, SRC ), + TOKEN_MAP_ENTRY( NONE, ID ), + XML_TOKEN_MAP_END +}; + +XFormsInstanceContext::XFormsInstanceContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + Reference<XPropertySet> xModel ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributes, aEmptyMap ), + mxModel( Reference<XModel>( xModel, UNO_QUERY ) ) +{ + DBG_ASSERT( mxModel.is(), "need model" ); +} + +XFormsInstanceContext::~XFormsInstanceContext() +{ +} + +SvXMLImportContext* XFormsInstanceContext::CreateChildContext( + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& ) +{ + SvXMLImportContext* pContext = NULL; + + // only the first element child of an xforms:instance element + // is used as an instance. The other children remainder must be + // ignored. + if( mxInstance.is() ) + { + GetImport().SetError( XMLERROR_XFORMS_ONLY_ONE_INSTANCE_ELEMENT, rLocalName ); + pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); + } + else + { + // create new DomBuilderContext. Save reference to tree in Model. + DomBuilderContext* pInstance = + new DomBuilderContext( GetImport(), nPrefix, rLocalName ); + mxInstance = pInstance->getTree(); + pContext = pInstance; + } + + DBG_ASSERT( pContext != NULL, "no context!" ); + return pContext; + +} + +void XFormsInstanceContext::EndElement() +{ + Sequence<PropertyValue> aSequence( 3 ); + PropertyValue* pSequence = aSequence.getArray(); + pSequence[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Instance") ); + pSequence[0].Value <<= mxInstance; + pSequence[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("ID") ); + pSequence[1].Value <<= msId; + pSequence[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("URL") ); + pSequence[2].Value <<= msURL; + + mxModel->getInstances()->insert( makeAny( aSequence ) ); +} + + +void XFormsInstanceContext::HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ) +{ + switch( nToken ) + { + case XML_SRC: + msURL = rValue; + break; + case XML_ID: + msId = rValue; + break; + default: + DBG_ERROR( "should not happen" ); + break; + } +} + +SvXMLImportContext* XFormsInstanceContext::HandleChild( + sal_uInt16, + sal_uInt16, + const OUString&, + const Reference<XAttributeList>& ) +{ + DBG_ERROR( "to be handled by CreateChildContext" ); + return NULL; +} diff --git a/xmloff/source/xforms/XFormsInstanceContext.hxx b/xmloff/source/xforms/XFormsInstanceContext.hxx new file mode 100644 index 000000000000..2772aef7fd2f --- /dev/null +++ b/xmloff/source/xforms/XFormsInstanceContext.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_XFORMSINSTANCECONTEXT_HXX +#define _XMLOFF_XFORMSINSTANCECONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace xml { namespace dom { class XDocument; } } + namespace beans { class XPropertySet; } + namespace xforms { class XModel; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + + +/** import the xforms:instance element */ +class XFormsInstanceContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::xforms::XModel> mxModel; + com::sun::star::uno::Reference<com::sun::star::xml::dom::XDocument> mxInstance; + rtl::OUString msId; + rtl::OUString msURL; + +public: + + XFormsInstanceContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName, + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xModel ); + virtual ~XFormsInstanceContext(); + + + // + // implement SvXMLImportContext & TokenContext methods: + // We override CreateChildContext, because we want to read + // arbitrary DOM elements. For the attributes, we use the + // TokenContext mechanism. + // + + virtual SvXMLImportContext* CreateChildContext( + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList >& xAttrList ); + + virtual void EndElement(); + +protected: + + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nNamespace, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); +}; + +#endif diff --git a/xmloff/source/xforms/XFormsModelContext.cxx b/xmloff/source/xforms/XFormsModelContext.cxx new file mode 100644 index 000000000000..074cbd7ddb8d --- /dev/null +++ b/xmloff/source/xforms/XFormsModelContext.cxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "XFormsModelContext.hxx" + +#include "XFormsBindContext.hxx" +#include "XFormsSubmissionContext.hxx" +#include "XFormsInstanceContext.hxx" +#include "SchemaContext.hxx" +#include "xformsapi.hxx" + +#include <xmloff/xmlimp.hxx> +#include "xmloff/xmlnmspe.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmltoken.hxx> +#include "xmloff/xmlerror.hxx" + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/xml/dom/XDocument.hpp> +#include <com/sun/star/util/XUpdatable.hpp> +#include <com/sun/star/xforms/XModel.hpp> + +#include <tools/debug.hxx> + + +using rtl::OUString; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::beans::XPropertySet; +using com::sun::star::util::XUpdatable; +using namespace com::sun::star::uno; +using namespace xmloff::token; + + + + +static SvXMLTokenMapEntry aAttributes[] = +{ + TOKEN_MAP_ENTRY( NONE, ID ), + TOKEN_MAP_ENTRY( NONE, SCHEMA ), + XML_TOKEN_MAP_END +}; + +static SvXMLTokenMapEntry aChildren[] = +{ + TOKEN_MAP_ENTRY( XFORMS, INSTANCE ), + TOKEN_MAP_ENTRY( XFORMS, BIND ), + TOKEN_MAP_ENTRY( XFORMS, SUBMISSION ), + TOKEN_MAP_ENTRY( XSD, SCHEMA ), + XML_TOKEN_MAP_END +}; + + +XFormsModelContext::XFormsModelContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ), + mxModel( lcl_createXFormsModel() ) +{ +} + +XFormsModelContext::~XFormsModelContext() +{ +} + + +Reference<XPropertySet> XFormsModelContext::getModel() +{ + return mxModel; +} + + +void XFormsModelContext::HandleAttribute( + sal_uInt16 nToken, + const OUString& rValue ) +{ + switch( nToken ) + { + case XML_ID: + mxModel->setPropertyValue( OUSTRING("ID"), makeAny( rValue ) ); + break; + case XML_SCHEMA: + GetImport().SetError( XMLERROR_XFORMS_NO_SCHEMA_SUPPORT ); + break; + default: + DBG_ERROR( "this should not happen" ); + break; + } +} + +SvXMLImportContext* XFormsModelContext::HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XAttributeList>& ) +{ + SvXMLImportContext* pContext = NULL; + + switch( nToken ) + { + case XML_INSTANCE: + pContext = new XFormsInstanceContext( GetImport(), nPrefix, rLocalName, + mxModel ); + break; + case XML_BIND: + pContext = new XFormsBindContext( GetImport(), nPrefix, rLocalName, + mxModel ); + break; + case XML_SUBMISSION: + pContext = new XFormsSubmissionContext( GetImport(), nPrefix, + rLocalName, mxModel ); + break; + case XML_SCHEMA: + pContext = new SchemaContext( + GetImport(), nPrefix, rLocalName, + Reference<com::sun::star::xforms::XModel>( mxModel, + UNO_QUERY_THROW ) + ->getDataTypeRepository() ); + break; + default: + DBG_ERROR( "Boooo!" ); + break; + } + + return pContext; +} + +void XFormsModelContext::EndElement() +{ + // update before putting model into document + Reference<XUpdatable> xUpdate( mxModel, UNO_QUERY ); + if( xUpdate.is() ) + xUpdate->update(); + + GetImport().initXForms(); + lcl_addXFormsModel( GetImport().GetModel(), getModel() ); +} diff --git a/xmloff/source/xforms/XFormsModelContext.hxx b/xmloff/source/xforms/XFormsModelContext.hxx new file mode 100644 index 000000000000..5731b606f1bb --- /dev/null +++ b/xmloff/source/xforms/XFormsModelContext.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_XFORMSMODELCONTEXT_HXX +#define _XMLOFF_XFORMSMODELCONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + +/** import the xforms:model element */ +class XFormsModelContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> mxModel; + +public: + + XFormsModelContext( SvXMLImport& rImport, + sal_uInt16 nPrfx, + const ::rtl::OUString& rLName ); + virtual ~XFormsModelContext(); + + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> getModel(); + + // + // implement SvXMLImportContext & TokenContext methods: + // + + virtual void EndElement(); + +protected: + + virtual void HandleAttribute( + sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); +}; + +#endif diff --git a/xmloff/source/xforms/XFormsModelExport.hxx b/xmloff/source/xforms/XFormsModelExport.hxx new file mode 100644 index 000000000000..2286d9ea2fb2 --- /dev/null +++ b/xmloff/source/xforms/XFormsModelExport.hxx @@ -0,0 +1,42 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_XFORMSMODELEXPORT_HXX +#define _XMLOFF_XFORMSMODELEXPORT_HXX + +#include <sal/types.h> + +class SvXMLExport; +namespace com { namespace sun { namespace star { + namespace uno { template<typename T> class Reference; } + namespace beans { class XPropertySet; } +} } } + +void exportXFormsModel( SvXMLExport&, + const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& ); + +#endif diff --git a/xmloff/source/xforms/XFormsSubmissionContext.cxx b/xmloff/source/xforms/XFormsSubmissionContext.cxx new file mode 100644 index 000000000000..7835cf5dc0a7 --- /dev/null +++ b/xmloff/source/xforms/XFormsSubmissionContext.cxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "XFormsSubmissionContext.hxx" + +#include "xformsapi.hxx" + +#include <xmloff/xmlimp.hxx> +#include "xmloff/xmlerror.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmltkmap.hxx> +#include "xmloff/xmlnmspe.hxx" +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> + +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/xforms/XModel.hpp> + +#include <tools/debug.hxx> + +using rtl::OUString; +using com::sun::star::beans::XPropertySet; +using com::sun::star::container::XNameContainer; +using com::sun::star::xml::sax::XAttributeList; +using com::sun::star::xforms::XModel; + +using namespace com::sun::star::uno; +using namespace xmloff::token; + + + + +static struct SvXMLTokenMapEntry aAttributeMap[] = +{ + TOKEN_MAP_ENTRY( NONE, ID ), + TOKEN_MAP_ENTRY( NONE, BIND ), + TOKEN_MAP_ENTRY( NONE, REF ), + TOKEN_MAP_ENTRY( NONE, ACTION ), + TOKEN_MAP_ENTRY( NONE, METHOD ), + TOKEN_MAP_ENTRY( NONE, VERSION ), + TOKEN_MAP_ENTRY( NONE, INDENT ), + TOKEN_MAP_ENTRY( NONE, MEDIATYPE ), + TOKEN_MAP_ENTRY( NONE, ENCODING ), + TOKEN_MAP_ENTRY( NONE, OMIT_XML_DECLARATION ), + TOKEN_MAP_ENTRY( NONE, STANDALONE ), + TOKEN_MAP_ENTRY( NONE, CDATA_SECTION_ELEMENTS ), + TOKEN_MAP_ENTRY( NONE, REPLACE ), + TOKEN_MAP_ENTRY( NONE, SEPARATOR ), + TOKEN_MAP_ENTRY( NONE, INCLUDENAMESPACEPREFIXES ), + XML_TOKEN_MAP_END +}; + +// helper function; see below +void lcl_fillNamespaceContainer( const SvXMLNamespaceMap&, + Reference<XNameContainer>& ); + +XFormsSubmissionContext::XFormsSubmissionContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const OUString& rLocalName, + const Reference<XPropertySet>& xModel ) : + TokenContext( rImport, nPrefix, rLocalName, aAttributeMap, aEmptyMap ), + mxSubmission() +{ + // register submission with model + DBG_ASSERT( xModel.is(), "need model" ); + Reference<XModel> xXModel( xModel, UNO_QUERY ); + DBG_ASSERT( xXModel.is(), "need XModel" ); + mxSubmission = xXModel->createSubmission().get(); + DBG_ASSERT( mxSubmission.is(), "can't create submission" ); + xXModel->getSubmissions()->insert( makeAny( mxSubmission ) ); +} + +XFormsSubmissionContext::~XFormsSubmissionContext() +{ +} + +Any toBool( const OUString& rValue ) +{ + Any aValue; + sal_Bool bValue; + if( SvXMLUnitConverter::convertBool( bValue, rValue ) ) + { + aValue <<= ( bValue ? true : false ); + } + return aValue; +} + +void XFormsSubmissionContext::HandleAttribute( sal_uInt16 nToken, + const OUString& rValue ) +{ + switch( nToken ) + { + case XML_ID: + lcl_setValue( mxSubmission, OUSTRING("ID"), rValue ); + break; + case XML_BIND: + lcl_setValue( mxSubmission, OUSTRING("Bind"), rValue ); + break; + case XML_REF: + lcl_setValue( mxSubmission, OUSTRING("Ref"), rValue ); + break; + case XML_ACTION: + lcl_setValue( mxSubmission, OUSTRING("Action"), rValue ); + break; + case XML_METHOD: + lcl_setValue( mxSubmission, OUSTRING("Method"), rValue ); + break; + case XML_VERSION: + lcl_setValue( mxSubmission, OUSTRING("Version"), rValue ); + break; + case XML_INDENT: + lcl_setValue( mxSubmission, OUSTRING("Indent"), toBool( rValue ) ); + break; + case XML_MEDIATYPE: + lcl_setValue( mxSubmission, OUSTRING("MediaType"), rValue ); + break; + case XML_ENCODING: + lcl_setValue( mxSubmission, OUSTRING("Encoding"), rValue ); + break; + case XML_OMIT_XML_DECLARATION: + lcl_setValue( mxSubmission, OUSTRING("OmitXmlDeclaration"), + toBool( rValue ) ); + break; + case XML_STANDALONE: + lcl_setValue( mxSubmission, OUSTRING("Standalone"), toBool( rValue ) ); + break; + case XML_CDATA_SECTION_ELEMENTS: + lcl_setValue( mxSubmission, OUSTRING("CDataSectionElement"), rValue ); + break; + case XML_REPLACE: + lcl_setValue( mxSubmission, OUSTRING("Replace"), rValue ); + break; + case XML_SEPARATOR: + lcl_setValue( mxSubmission, OUSTRING("Separator"), rValue ); + break; + case XML_INCLUDENAMESPACEPREFIXES: + lcl_setValue( mxSubmission, OUSTRING("IncludeNamespacePrefixes"), rValue ); + break; + default: + DBG_ERROR( "unknown attribute" ); + break; + } +} + +/** will be called for each child element */ +SvXMLImportContext* XFormsSubmissionContext::HandleChild( + sal_uInt16, + sal_uInt16, + const OUString&, + const Reference<XAttributeList>& ) +{ + DBG_ERROR( "no children supported" ); + return NULL; +} diff --git a/xmloff/source/xforms/XFormsSubmissionContext.hxx b/xmloff/source/xforms/XFormsSubmissionContext.hxx new file mode 100644 index 000000000000..00cd2849603b --- /dev/null +++ b/xmloff/source/xforms/XFormsSubmissionContext.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XMLOFF_XFORMSSUBMISSIONCONTEXT_HXX +#define _XMLOFF_XFORMSSUBMISSIONCONTEXT_HXX + + +// +// include for parent class and members +// + +#include "TokenContext.hxx" +#include <com/sun/star/uno/Reference.hxx> + + +// +// forward declarations +// + +namespace com { namespace sun { namespace star { + namespace xml { namespace sax { class XAttributeList; } } + namespace beans { class XPropertySet; } +} } } +namespace rtl { class OUString; } +class SvXMLImport; +class SvXMLImportContext; + + +/** import the xforms:submission element */ +class XFormsSubmissionContext : public TokenContext +{ + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> mxSubmission; + +public: + + XFormsSubmissionContext( SvXMLImport& rImport, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xModel ); + virtual ~XFormsSubmissionContext(); + + + // + // implement TokenContext methods: + // + +protected: + virtual void HandleAttribute( sal_uInt16 nToken, + const rtl::OUString& rValue ); + + virtual SvXMLImportContext* HandleChild( + sal_uInt16 nToken, + sal_uInt16 nNamespace, + const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList ); + +}; + +#endif diff --git a/xmloff/source/xforms/xformsapi.cxx b/xmloff/source/xforms/xformsapi.cxx new file mode 100644 index 000000000000..794798c5366a --- /dev/null +++ b/xmloff/source/xforms/xformsapi.cxx @@ -0,0 +1,348 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "xformsapi.hxx" + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/xforms/XFormsSupplier.hpp> +#include <com/sun/star/xforms/XDataTypeRepository.hpp> +#include <com/sun/star/xforms/XModel.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/xsd/DataTypeClass.hpp> + +#include <unotools/processfactory.hxx> +#include <tools/debug.hxx> + +#include <xmloff/xmltoken.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmlnmspe.hxx> +#include <xmloff/xmltkmap.hxx> + +using rtl::OUString; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::UNO_QUERY_THROW; +using com::sun::star::beans::XPropertySet; +using com::sun::star::container::XNameAccess; +using com::sun::star::lang::XMultiServiceFactory; +using com::sun::star::xforms::XFormsSupplier; +using com::sun::star::xforms::XDataTypeRepository; +using com::sun::star::container::XNameContainer; +using utl::getProcessServiceFactory; +using com::sun::star::uno::makeAny; +using com::sun::star::uno::Any; +using com::sun::star::uno::Exception; + +using namespace com::sun::star; +using namespace xmloff::token; + +Reference<XPropertySet> lcl_createPropertySet( const OUString& rServiceName ) +{ + Reference<XMultiServiceFactory> xFactory = getProcessServiceFactory(); + DBG_ASSERT( xFactory.is(), "can't get service factory" ); + + Reference<XPropertySet> xModel( xFactory->createInstance( rServiceName ), + UNO_QUERY_THROW ); + DBG_ASSERT( xModel.is(), "can't create model" ); + + return xModel; +} + +Reference<XPropertySet> lcl_createXFormsModel() +{ + return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Model" ) ); +} + +Reference<XPropertySet> lcl_createXFormsBinding() +{ + return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Binding" ) ); +} + +void lcl_addXFormsModel( + const Reference<frame::XModel>& xDocument, + const Reference<XPropertySet>& xModel ) +{ + bool bSuccess = false; + try + { + Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY ); + if( xSupplier.is() ) + { + Reference<XNameContainer> xForms = xSupplier->getXForms(); + if( xForms.is() ) + { + OUString sName; + xModel->getPropertyValue( OUSTRING("ID")) >>= sName; + xForms->insertByName( sName, makeAny( xModel ) ); + bSuccess = true; + } + } + } + catch( const Exception& ) + { + ; // no success! + } + + // TODO: implement proper error handling + DBG_ASSERT( bSuccess, "can't import model" ); +} + +Reference<XPropertySet> lcl_findXFormsBindingOrSubmission( + Reference<frame::XModel>& xDocument, + const rtl::OUString& rBindingID, + bool bBinding ) +{ + // find binding by iterating over all models, and look for the + // given binding ID + + Reference<XPropertySet> xRet; + try + { + // get supplier + Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY ); + if( xSupplier.is() ) + { + // get XForms models + Reference<XNameContainer> xForms = xSupplier->getXForms(); + if( xForms.is() ) + { + // iterate over all models + Sequence<OUString> aNames = xForms->getElementNames(); + const OUString* pNames = aNames.getConstArray(); + sal_Int32 nNames = aNames.getLength(); + for( sal_Int32 n = 0; (n < nNames) && !xRet.is(); n++ ) + { + Reference<xforms::XModel> xModel( + xForms->getByName( pNames[n] ), UNO_QUERY ); + if( xModel.is() ) + { + // ask model for bindings + Reference<XNameAccess> xBindings( + bBinding + ? xModel->getBindings() + : xModel->getSubmissions(), + UNO_QUERY_THROW ); + + // finally, ask binding for name + if( xBindings->hasByName( rBindingID ) ) + xRet.set( xBindings->getByName( rBindingID ), + UNO_QUERY ); + } + } + } + } + } + catch( const Exception& ) + { + ; // no success! + } + + // TODO: if (!xRet.is()) rImport.SetError(...); + + return xRet; +} + +Reference<XPropertySet> lcl_findXFormsBinding( + Reference<frame::XModel>& xDocument, + const rtl::OUString& rBindingID ) +{ + return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, true ); +} + +Reference<XPropertySet> lcl_findXFormsSubmission( + Reference<frame::XModel>& xDocument, + const rtl::OUString& rBindingID ) +{ + return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, false ); +} + +void lcl_setValue( Reference<XPropertySet>& xPropertySet, + const OUString& rName, + const Any rAny ) +{ + xPropertySet->setPropertyValue( rName, rAny ); +} + + +Reference<XPropertySet> lcl_getXFormsModel( const Reference<frame::XModel>& xDoc ) +{ + Reference<XPropertySet> xRet; + try + { + Reference<XFormsSupplier> xSupplier( xDoc, UNO_QUERY ); + if( xSupplier.is() ) + { + Reference<XNameContainer> xForms = xSupplier->getXForms(); + if( xForms.is() ) + { + Sequence<OUString> aNames = xForms->getElementNames(); + if( aNames.getLength() > 0 ) + xRet.set( xForms->getByName( aNames[0] ), UNO_QUERY ); + } + } + } + catch( const Exception& ) + { + ; // no success! + } + + return xRet; +} + +#define TOKEN_MAP_ENTRY(NAMESPACE,TOKEN) { XML_NAMESPACE_##NAMESPACE, xmloff::token::XML_##TOKEN, xmloff::token::XML_##TOKEN } +static SvXMLTokenMapEntry aTypes[] = +{ + TOKEN_MAP_ENTRY( XSD, STRING ), + TOKEN_MAP_ENTRY( XSD, DECIMAL ), + TOKEN_MAP_ENTRY( XSD, DOUBLE ), + TOKEN_MAP_ENTRY( XSD, FLOAT ), + TOKEN_MAP_ENTRY( XSD, BOOLEAN ), + TOKEN_MAP_ENTRY( XSD, ANYURI ), + TOKEN_MAP_ENTRY( XSD, DATETIME_XSD ), + TOKEN_MAP_ENTRY( XSD, DATE ), + TOKEN_MAP_ENTRY( XSD, TIME ), + TOKEN_MAP_ENTRY( XSD, YEAR ), + TOKEN_MAP_ENTRY( XSD, MONTH ), + TOKEN_MAP_ENTRY( XSD, DAY ), + XML_TOKEN_MAP_END +}; + +sal_uInt16 lcl_getTypeClass( + const Reference<XDataTypeRepository>& + #ifdef DBG_UTIL + xRepository + #endif + , + const SvXMLNamespaceMap& rNamespaceMap, + const OUString& rXMLName ) +{ + // translate name into token for local name + OUString sLocalName; + sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName); + SvXMLTokenMap aMap( aTypes ); + sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName ); + + sal_uInt16 nTypeClass = com::sun::star::xsd::DataTypeClass::STRING; + if( mnToken != XML_TOK_UNKNOWN ) + { + // we found an XSD name: then get the proper API name for it + DBG_ASSERT( xRepository.is(), "can't find type without repository"); + switch( mnToken ) + { + case XML_STRING: + nTypeClass = com::sun::star::xsd::DataTypeClass::STRING; + break; + case XML_ANYURI: + nTypeClass = com::sun::star::xsd::DataTypeClass::anyURI; + break; + case XML_DECIMAL: + nTypeClass = com::sun::star::xsd::DataTypeClass::DECIMAL; + break; + case XML_DOUBLE: + nTypeClass = com::sun::star::xsd::DataTypeClass::DOUBLE; + break; + case XML_FLOAT: + nTypeClass = com::sun::star::xsd::DataTypeClass::FLOAT; + break; + case XML_BOOLEAN: + nTypeClass = com::sun::star::xsd::DataTypeClass::BOOLEAN; + break; + case XML_DATETIME_XSD: + nTypeClass = com::sun::star::xsd::DataTypeClass::DATETIME; + break; + case XML_DATE: + nTypeClass = com::sun::star::xsd::DataTypeClass::DATE; + break; + case XML_TIME: + nTypeClass = com::sun::star::xsd::DataTypeClass::TIME; + break; + case XML_YEAR: + nTypeClass = com::sun::star::xsd::DataTypeClass::gYear; + break; + case XML_DAY: + nTypeClass = com::sun::star::xsd::DataTypeClass::gDay; + break; + case XML_MONTH: + nTypeClass = com::sun::star::xsd::DataTypeClass::gMonth; + break; + + /* data types not yet supported: + nTypeClass = com::sun::star::xsd::DataTypeClass::DURATION; + nTypeClass = com::sun::star::xsd::DataTypeClass::gYearMonth; + nTypeClass = com::sun::star::xsd::DataTypeClass::gMonthDay; + nTypeClass = com::sun::star::xsd::DataTypeClass::hexBinary; + nTypeClass = com::sun::star::xsd::DataTypeClass::base64Binary; + nTypeClass = com::sun::star::xsd::DataTypeClass::QName; + nTypeClass = com::sun::star::xsd::DataTypeClass::NOTATION; + */ + } + } + + return nTypeClass; +} + + +rtl::OUString lcl_getTypeName( + const Reference<XDataTypeRepository>& xRepository, + const SvXMLNamespaceMap& rNamespaceMap, + const OUString& rXMLName ) +{ + OUString sLocalName; + sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName); + SvXMLTokenMap aMap( aTypes ); + sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName ); + return ( mnToken == XML_TOK_UNKNOWN ) + ? rXMLName + : lcl_getBasicTypeName( xRepository, rNamespaceMap, rXMLName ); +} + +rtl::OUString lcl_getBasicTypeName( + const Reference<XDataTypeRepository>& xRepository, + const SvXMLNamespaceMap& rNamespaceMap, + const OUString& rXMLName ) +{ + OUString sTypeName = rXMLName; + try + { + sTypeName = + xRepository->getBasicDataType( + lcl_getTypeClass( xRepository, rNamespaceMap, rXMLName ) ) + ->getName(); + } + catch( const Exception& ) + { + DBG_ERROR( "exception during type creation" ); + } + return sTypeName; +} diff --git a/xmloff/source/xforms/xformsapi.hxx b/xmloff/source/xforms/xformsapi.hxx new file mode 100644 index 000000000000..4b5987594478 --- /dev/null +++ b/xmloff/source/xforms/xformsapi.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLOFF_XFORMSAPI_HXX +#define _XMLOFF_XFORMSAPI_HXX + +// +// this is a collection of several functions to make dealing with the XForms +// API a little easier +// + +#include <com/sun/star/uno/Any.hxx> + +namespace rtl { class OUString; } +namespace com { namespace sun { namespace star { + namespace beans { class XPropertySet; } + namespace frame { class XModel; } + namespace uno { template<class A> class Reference; } + namespace xforms { class XDataTypeRepository; } +} } } +class SvXMLNamespaceMap; + + +#define OUSTRING(msg) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(msg)) + +com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> lcl_createXFormsModel(); + +com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> lcl_createXFormsBinding(); + +void lcl_addXFormsModel( + const com::sun::star::uno::Reference<com::sun::star::frame::XModel>& xDocument, + const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xModel ); + +com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> lcl_findXFormsBinding( com::sun::star::uno::Reference<com::sun::star::frame::XModel>&, const rtl::OUString& ); + +com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> lcl_findXFormsSubmission( com::sun::star::uno::Reference<com::sun::star::frame::XModel>&, const rtl::OUString& ); + +void lcl_setValue( + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet, + const rtl::OUString& rName, + const com::sun::star::uno::Any rAny ); + +template<typename T> +void lcl_setValue( + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet, + const rtl::OUString& rName, + T& aValue ) +{ + lcl_setValue( xPropSet, rName, com::sun::star::uno::makeAny( aValue ) ); +} + + +com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> lcl_getXFormsModel( const com::sun::star::uno::Reference<com::sun::star::frame::XModel>& ); + +sal_uInt16 lcl_getTypeClass( + const com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& xRepository, + const SvXMLNamespaceMap& rNamespaceMap, + const rtl::OUString& rXMLName ); + +rtl::OUString lcl_getTypeName( + const com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& xRepository, + const SvXMLNamespaceMap& rNamespaceMap, + const rtl::OUString& rXMLName ); + +rtl::OUString lcl_getBasicTypeName( + const com::sun::star::uno::Reference<com::sun::star::xforms::XDataTypeRepository>& xRepository, + const SvXMLNamespaceMap& rNamespaceMap, + const rtl::OUString& rXMLName ); + +#endif diff --git a/xmloff/source/xforms/xformsexport.cxx b/xmloff/source/xforms/xformsexport.cxx new file mode 100644 index 000000000000..3d90170f11f4 --- /dev/null +++ b/xmloff/source/xforms/xformsexport.cxx @@ -0,0 +1,835 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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(); + } +} diff --git a/xmloff/source/xforms/xformsimport.cxx b/xmloff/source/xforms/xformsimport.cxx new file mode 100644 index 000000000000..84908444498e --- /dev/null +++ b/xmloff/source/xforms/xformsimport.cxx @@ -0,0 +1,206 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include "XFormsModelContext.hxx" +#include <vector> +#include <utility> +#include "xmloff/xformsimport.hxx" +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/form/binding/XValueBinding.hpp> +#include <com/sun/star/form/binding/XBindableValue.hpp> +#include <com/sun/star/form/binding/XListEntrySource.hpp> +#include <com/sun/star/form/binding/XListEntrySink.hpp> +#include <com/sun/star/form/submission/XSubmission.hpp> +#include <com/sun/star/form/submission/XSubmissionSupplier.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <rtl/ustring.hxx> +#include <xformsapi.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <tools/diagnose_ex.h> + +using std::pair; +using com::sun::star::uno::Reference; +using com::sun::star::uno::Exception; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::UNO_QUERY_THROW; +using com::sun::star::uno::UNO_SET_THROW; +using com::sun::star::uno::Sequence; +using com::sun::star::beans::XPropertySet; +using com::sun::star::beans::XPropertySetInfo; +using com::sun::star::beans::PropertyValue; +using com::sun::star::frame::XModel; +using com::sun::star::container::XNameAccess; +using com::sun::star::form::binding::XValueBinding; +using com::sun::star::form::binding::XBindableValue; +using com::sun::star::form::binding::XListEntrySource; +using com::sun::star::form::binding::XListEntrySink; +using com::sun::star::form::submission::XSubmission; +using com::sun::star::form::submission::XSubmissionSupplier; +using rtl::OUString; + +SvXMLImportContext* createXFormsModelContext( + SvXMLImport& rImport, + sal_uInt16 nPrefix, + const rtl::OUString& rLocalName ) +{ + return new XFormsModelContext( rImport, nPrefix, rLocalName ); +} + +void bindXFormsValueBinding( + Reference<XModel> xModel, + pair<Reference<XPropertySet>,OUString> aPair ) +{ + Reference<XBindableValue> xBindable( + aPair.first, + UNO_QUERY ); + Reference<XValueBinding> xBinding( + lcl_findXFormsBinding( xModel, aPair.second ), + UNO_QUERY ); + + if( xBindable.is() && xBinding.is() ) + { + try + { + xBindable->setValueBinding( xBinding ); + } + catch( const Exception& ) + { + // ignore problems during binding + // TODO: call XML error handling + } + } +} + +void bindXFormsListBinding( + Reference<XModel> xModel, + ::pair<Reference<XPropertySet>,OUString> aPair ) +{ + Reference<XListEntrySink> xListEntrySink( + aPair.first, + UNO_QUERY ); + Reference<XListEntrySource> xListEntrySource( + lcl_findXFormsBinding( xModel, aPair.second ), + UNO_QUERY ); + + if( xListEntrySink.is() && xListEntrySource.is() ) + { + try + { + xListEntrySink->setListEntrySource( xListEntrySource ); + } + catch( const Exception& ) + { + // ignore problems during binding + // TODO: call XML error handling + } + } +} + +void bindXFormsSubmission( + Reference<XModel> xModel, + pair<Reference<XPropertySet>,OUString> aPair ) +{ + Reference<XSubmissionSupplier> xSubmissionSupp( aPair.first, UNO_QUERY ); + Reference<XSubmission> xSubmission( + lcl_findXFormsSubmission( xModel, aPair.second ), + UNO_QUERY ); + + if( xSubmissionSupp.is() && xSubmission.is() ) + { + try + { + xSubmissionSupp->setSubmission( xSubmission ); + } + catch( const Exception& ) + { + // ignore problems during binding + // TODO: call XML error handling + } + } +} + +void applyXFormsSettings( const Reference< XNameAccess >& _rXForms, const Sequence< PropertyValue >& _rSettings ) +{ + OSL_PRECOND( _rXForms.is(), "applyXFormsSettings: invalid XForms container!" ); + if ( !_rXForms.is() ) + return; + + ::comphelper::NamedValueCollection aSettings( _rSettings ); + Reference< XNameAccess > xModelSettings( aSettings.get( "XFormModels" ), UNO_QUERY ); + if ( !xModelSettings.is() ) + { + OSL_ENSURE( false, "applyXFormsSettings: wrong type for the XFormModels settings!" ); + return; + } + + try + { + Sequence< ::rtl::OUString > aSettingsForModels( xModelSettings->getElementNames() ); + for ( const ::rtl::OUString* pModelName = aSettingsForModels.getConstArray(); + pModelName != aSettingsForModels.getConstArray() + aSettingsForModels.getLength(); + ++pModelName + ) + { + // the settings for this particular model + Sequence< PropertyValue > aModelSettings; + OSL_VERIFY( xModelSettings->getByName( *pModelName ) >>= aModelSettings ); + + // the model itself + if ( !_rXForms->hasByName( *pModelName ) ) + { + OSL_ENSURE( false, "applyXFormsSettings: have settings for a non-existent XForms model!" ); + continue; + } + + // propagate the settings, being tolerant by omitting properties which are not supported + Reference< XPropertySet > xModelProps( _rXForms->getByName( *pModelName ), UNO_QUERY_THROW ); + Reference< XPropertySetInfo > xModelPSI( xModelProps->getPropertySetInfo(), UNO_SET_THROW ); + + for ( const PropertyValue* pSetting = aModelSettings.getConstArray(); + pSetting != aModelSettings.getConstArray() + aModelSettings.getLength(); + ++pSetting + ) + { + if ( !xModelPSI->hasPropertyByName( pSetting->Name ) ) + { + OSL_ENSURE( false, "applyXFormsSettings: non-existent model property!" ); + continue; + } + + xModelProps->setPropertyValue( pSetting->Name, pSetting->Value ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} |