diff options
Diffstat (limited to 'forms/source/xforms/datatypes.cxx')
-rw-r--r-- | forms/source/xforms/datatypes.cxx | 306 |
1 files changed, 263 insertions, 43 deletions
diff --git a/forms/source/xforms/datatypes.cxx b/forms/source/xforms/datatypes.cxx index 2f78df49b747..91cb67efcf9f 100644 --- a/forms/source/xforms/datatypes.cxx +++ b/forms/source/xforms/datatypes.cxx @@ -24,12 +24,15 @@ #include <property.hxx> #include <strings.hrc> #include "convert.hxx" +#include <comphelper/processfactory.hxx> #include <com/sun/star/xsd/DataTypeClass.hpp> #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> +#include <o3tl/string_view.hxx> #include <tools/datetime.hxx> #include <rtl/math.hxx> #include <sal/log.hxx> +#include <utility> namespace xforms @@ -38,7 +41,6 @@ namespace xforms using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Any; - using ::com::sun::star::uno::makeAny; using ::com::sun::star::util::Date; using ::com::sun::star::util::Time; using ::com::sun::star::util::DateTime; @@ -53,11 +55,10 @@ namespace xforms using namespace ::frm; U_NAMESPACE_USE - OXSDDataType::OXSDDataType( const OUString& _rName, sal_Int16 _nTypeClass ) - :OXSDDataType_PBase( m_aBHelper ) - ,m_bIsBasic( true ) + OXSDDataType::OXSDDataType( OUString _aName, sal_Int16 _nTypeClass ) + :m_bIsBasic( true ) ,m_nTypeClass( _nTypeClass ) - ,m_sName( _rName ) + ,m_sName(std::move( _aName )) ,m_nWST( WhiteSpaceTreatment::Preserve ) ,m_bPatternMatcherDirty( true ) { @@ -97,10 +98,10 @@ namespace xforms } - IMPLEMENT_FORWARD_XINTERFACE2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer ) + IMPLEMENT_FORWARD_XINTERFACE2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer2 ) - IMPLEMENT_FORWARD_XTYPEPROVIDER2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OXSDDataType, OXSDDataType_Base, ::comphelper::OPropertyContainer2 ) OUString SAL_CALL OXSDDataType::getName( ) { @@ -111,7 +112,7 @@ namespace xforms void SAL_CALL OXSDDataType::setName( const OUString& aName ) { // TODO: check the name for conflicts in the repository - setFastPropertyValue( PROPERTY_ID_NAME, makeAny(aName) ); + setFastPropertyValue( PROPERTY_ID_NAME, Any(aName) ); SAL_WARN_IF( m_sName != aName, "forms.misc", "OXSDDataType::setName: inconsistency!" ); } @@ -124,7 +125,7 @@ namespace xforms void SAL_CALL OXSDDataType::setPattern( const OUString& _pattern ) { - setFastPropertyValue( PROPERTY_ID_XSD_PATTERN, makeAny(_pattern) ); + setFastPropertyValue( PROPERTY_ID_XSD_PATTERN, Any(_pattern) ); SAL_WARN_IF( m_sPattern != _pattern, "forms.misc", "OXSDDataType::setPattern: inconsistency!" ); } @@ -137,7 +138,7 @@ namespace xforms void SAL_CALL OXSDDataType::setWhiteSpaceTreatment( sal_Int16 _whitespacetreatment ) { - setFastPropertyValue( PROPERTY_ID_XSD_WHITESPACE, makeAny(_whitespacetreatment) ); + setFastPropertyValue( PROPERTY_ID_XSD_WHITESPACE, Any(_whitespacetreatment) ); SAL_WARN_IF( m_nWST != _whitespacetreatment, "forms.misc", "OXSDDataType::setWhiteSpaceTreatment: inconsistency!" ); } @@ -156,7 +157,7 @@ namespace xforms sal_Bool OXSDDataType::validate( const OUString& sValue ) { - return bool(_validate( sValue )); + return bool(!_validate( sValue )); } @@ -231,29 +232,26 @@ namespace xforms } - sal_Bool OXSDDataType::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) + bool OXSDDataType::convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) { // let the base class do the conversion - if ( !OXSDDataType_PBase::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue ) ) + if ( !::comphelper::OPropertyContainer2::convertFastPropertyValue( rGuard, _rConvertedValue, _rOldValue, _nHandle, _rValue ) ) return false; // sanity checks OUString sErrorMessage; if ( !checkPropertySanity( _nHandle, _rConvertedValue, sErrorMessage ) ) { - IllegalArgumentException aException; - aException.Message = sErrorMessage; - aException.Context = *this; - throw aException; + throw IllegalArgumentException(sErrorMessage, *this, 0); } return true; } - void SAL_CALL OXSDDataType::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) + void OXSDDataType::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 _nHandle, const Any& _rValue ) { - OXSDDataType_PBase::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + ::comphelper::OPropertyContainer2::setFastPropertyValue_NoBroadcast( rGuard, _nHandle, _rValue ); if ( _nHandle == PROPERTY_ID_XSD_PATTERN ) m_bPatternMatcherDirty = true; } @@ -281,37 +279,37 @@ namespace xforms void SAL_CALL OXSDDataType::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) { - OXSDDataType_PBase::setPropertyValue( aPropertyName, aValue ); + ::comphelper::OPropertyContainer2::setPropertyValue( aPropertyName, aValue ); } Any SAL_CALL OXSDDataType::getPropertyValue( const OUString& PropertyName ) { - return OXSDDataType_PBase::getPropertyValue( PropertyName ); + return ::comphelper::OPropertyContainer2::getPropertyValue( PropertyName ); } void SAL_CALL OXSDDataType::addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) { - OXSDDataType_PBase::addPropertyChangeListener( aPropertyName, xListener ); + ::comphelper::OPropertyContainer2::addPropertyChangeListener( aPropertyName, xListener ); } void SAL_CALL OXSDDataType::removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) { - OXSDDataType_PBase::removePropertyChangeListener( aPropertyName, aListener ); + ::comphelper::OPropertyContainer2::removePropertyChangeListener( aPropertyName, aListener ); } void SAL_CALL OXSDDataType::addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) { - OXSDDataType_PBase::addVetoableChangeListener( PropertyName, aListener ); + ::comphelper::OPropertyContainer2::addVetoableChangeListener( PropertyName, aListener ); } void SAL_CALL OXSDDataType::removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) { - OXSDDataType_PBase::removeVetoableChangeListener( PropertyName, aListener ); + ::comphelper::OPropertyContainer2::removeVetoableChangeListener( PropertyName, aListener ); } OValueLimitedType_Base::OValueLimitedType_Base( const OUString& _rName, sal_Int16 _nTypeClass ) @@ -344,10 +342,11 @@ namespace xforms } - void SAL_CALL OValueLimitedType_Base::setFastPropertyValue_NoBroadcast( + void OValueLimitedType_Base::setFastPropertyValue_NoBroadcast( + std::unique_lock<std::mutex>& rGuard, sal_Int32 _nHandle, const css::uno::Any& _rValue ) { - OXSDDataType::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + OXSDDataType::setFastPropertyValue_NoBroadcast( rGuard, _nHandle, _rValue ); // if one of our limit properties has been set, translate it into a double // value, for later efficient validation @@ -403,7 +402,7 @@ namespace xforms rtl_math_ConversionStatus eStatus; sal_Int32 nEnd; double f = ::rtl::math::stringToDouble( - rValue, '.', u'\0', &eStatus, &nEnd ); + rValue.replace(',','.'), '.', u'\0', &eStatus, &nEnd ); // error checking... bool bReturn = false; @@ -512,7 +511,7 @@ namespace xforms { sal_Int32 nValue( 0 ); OSL_VERIFY( _rNewValue >>= nValue ); - if ( nValue <= 0 ) + if ( nValue < 0 ) _rErrorMessage = "Length limits must denote positive integer values."; // TODO/eforms: localize the error message } @@ -575,6 +574,131 @@ namespace xforms return sInfo.makeStringAndClear(); } + OAnyURIType::OAnyURIType( const OUString& _rName, sal_Int16 _nTypeClass ) + : OAnyURIType_Base(_rName, _nTypeClass) + , m_xURLTransformer(css::util::URLTransformer::create(::comphelper::getProcessComponentContext())) + { + } + + void OAnyURIType::registerProperties() + { + OAnyURIType_Base::registerProperties(); + + registerMayBeVoidProperty( PROPERTY_XSD_LENGTH, PROPERTY_ID_XSD_LENGTH, css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEVOID, + &m_aLength, cppu::UnoType<sal_Int32>::get() ); + + registerMayBeVoidProperty( PROPERTY_XSD_MIN_LENGTH, PROPERTY_ID_XSD_MIN_LENGTH, css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEVOID, + &m_aMinLength, cppu::UnoType<sal_Int32>::get() ); + + registerMayBeVoidProperty( PROPERTY_XSD_MAX_LENGTH, PROPERTY_ID_XSD_MAX_LENGTH, css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEVOID, + &m_aMaxLength, cppu::UnoType<sal_Int32>::get() ); + } + + rtl::Reference<OXSDDataType> OAnyURIType::createClone( const OUString& _rName ) const + { + return new OAnyURIType( _rName, getTypeClass() ); + } + + void OAnyURIType::initializeClone( const OXSDDataType& _rCloneSource ) + { + OAnyURIType_Base::initializeClone( _rCloneSource ); + initializeTypedClone( static_cast< const OAnyURIType& >( _rCloneSource ) ); + } + + + + void OAnyURIType::initializeTypedClone( const OAnyURIType& _rCloneSource ) + { + m_aLength = _rCloneSource.m_aLength; + m_aMinLength = _rCloneSource.m_aMinLength; + m_aMaxLength = _rCloneSource.m_aMaxLength; + } + + + bool OAnyURIType::checkPropertySanity( sal_Int32 _nHandle, const Any& _rNewValue, OUString& _rErrorMessage ) + { + // let the base class do the conversion + if ( !OAnyURIType_Base::checkPropertySanity( _nHandle, _rNewValue, _rErrorMessage ) ) + return false; + + _rErrorMessage.clear(); + switch ( _nHandle ) + { + case PROPERTY_ID_XSD_LENGTH: + case PROPERTY_ID_XSD_MIN_LENGTH: + case PROPERTY_ID_XSD_MAX_LENGTH: + { + sal_Int32 nValue( 0 ); + OSL_VERIFY( _rNewValue >>= nValue ); + if ( nValue < 0 ) + _rErrorMessage = "Length limits must denote positive integer values."; + // TODO/eforms: localize the error message + } + break; + } + + return _rErrorMessage.isEmpty(); + } + + + TranslateId OAnyURIType::_validate( const OUString& rValue ) + { + // check regexp, whitespace etc. in parent class + TranslateId pReason = OAnyURIType_Base::_validate( rValue ); + + if (!pReason) + { + // check AnyURI constraints + sal_Int32 nLength = rValue.getLength(); + sal_Int32 nLimit = 0; + if ( m_aLength >>= nLimit ) + { + if ( nLimit != nLength ) + pReason = RID_STR_XFORMS_VALUE_LENGTH; + } + else + { + if ( ( m_aMaxLength >>= nLimit ) && ( nLength > nLimit ) ) + pReason = RID_STR_XFORMS_VALUE_MAX_LENGTH; + else if ( ( m_aMinLength >>= nLimit ) && ( nLength < nLimit ) ) + pReason = RID_STR_XFORMS_VALUE_MIN_LENGTH; + } + // check URL + css::util::URL aCommandURL; + aCommandURL.Complete = rValue; + if (!m_xURLTransformer->parseStrict(aCommandURL)) + pReason = RID_STR_XFORMS_INVALID_VALUE; + + } + return pReason; + } + + OUString OAnyURIType::_explainInvalid(TranslateId rReason) + { + sal_Int32 nValue = 0; + OUStringBuffer sInfo; + if (rReason == RID_STR_XFORMS_VALUE_LENGTH) + { + if( m_aLength >>= nValue ) + sInfo.append( nValue ); + } + else if (rReason == RID_STR_XFORMS_VALUE_MAX_LENGTH) + { + if( m_aMaxLength >>= nValue ) + sInfo.append( nValue ); + } + else if (rReason == RID_STR_XFORMS_VALUE_MIN_LENGTH) + { + if( m_aMinLength >>= nValue ) + sInfo.append( nValue ); + } + else if (rReason) + { + sInfo.append(OAnyURIType_Base::_explainInvalid(rReason)); + } + return sInfo.makeStringAndClear(); + } + OBooleanType::OBooleanType( const OUString& _rName ) :OBooleanType_Base( _rName, DataTypeClass::BOOLEAN ) { @@ -730,7 +854,15 @@ namespace xforms bool ODateType::_getValue( const OUString& value, double& fValue ) { - Any aTypeValue = Convert::get().toAny( value, getCppuType() ); + Any aTypeValue; + try + { + aTypeValue = Convert::get().toAny( value, getCppuType() ); + } + catch (com::sun::star::lang::IllegalArgumentException) + { + return false; + } Date aValue; if ( !( aTypeValue >>= aValue ) ) @@ -779,7 +911,15 @@ namespace xforms bool OTimeType::_getValue( const OUString& value, double& fValue ) { - Any aTypedValue = Convert::get().toAny( value, getCppuType() ); + Any aTypedValue; + try + { + aTypedValue = Convert::get().toAny( value, getCppuType() ); + } + catch (com::sun::star::lang::IllegalArgumentException) + { + return false; + } css::util::Time aValue; if ( !( aTypedValue >>= aValue ) ) @@ -851,7 +991,15 @@ namespace xforms bool ODateTimeType::_getValue( const OUString& value, double& fValue ) { - Any aTypedValue = Convert::get().toAny( value, getCppuType() ); + Any aTypedValue; + try + { + aTypedValue = Convert::get().toAny( value, getCppuType() ); + } + catch (com::sun::star::uno::RuntimeException) + { + return false; + } DateTime aValue; if ( !( aTypedValue >>= aValue ) ) @@ -896,21 +1044,93 @@ namespace xforms initializeTypedClone( static_cast< const OShortIntegerType& >( _rCloneSource ) ); } - bool OShortIntegerType::_getValue( const OUString& value, double& fValue ) + static bool lcl_getValueYear( std::u16string_view value, double& fValue ) + { + if (value.size() > 4) + { + fValue = 0; + return false; + } + if (o3tl::equalsAscii(value, "0")) + { + fValue = 0; + return true; + } + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 0 || + int32Value > 10000 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); + return true; + } + + static bool lcl_getValueMonth( std::u16string_view value, double& fValue ) { - fValue = static_cast<double>(static_cast<sal_Int16>(value.toInt32())); - // TODO/eforms - // this does not care for values which do not fit into a sal_Int16, but simply - // cuts them down. A better implementation here should probably return <FALSE/> - // for those values. - // Else, we may have a situation where the UI claims an input to be valid - // (say "12345678"), while internally, and at submission time, this is cut to - // some smaller value. + if (value.size() > 2) + { + fValue = 0; + return false; + } + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 1 || + int32Value > 12 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); + return true; + } - // Additionally, this of course does not care for strings which are no numbers... + static bool lcl_getValueDay( std::u16string_view value, double& fValue ) + { + if (value.size() > 2) + { + fValue = 0; + return false; + } + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 1 || + int32Value > 31 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); return true; } + bool OShortIntegerType::_getValue( const OUString& value, double& fValue ) + { + switch (this->getTypeClass()) + { + case css::xsd::DataTypeClass::gYear: + return lcl_getValueYear(value, fValue); + + case css::xsd::DataTypeClass::gMonth: + return lcl_getValueMonth(value, fValue); + + case css::xsd::DataTypeClass::gDay: + return lcl_getValueDay(value, fValue); + default: + // for the moment, the only types which derive from OShortIntegerType are: + // gYear, gMonth and gDay, see ODataTypeRepository ctr + return false; + } + } + OUString OShortIntegerType::typedValueAsHumanReadableString( const Any& _rValue ) const { @@ -953,7 +1173,7 @@ css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL ODerivedDataType< C template< typename CONCRETE_DATA_TYPE_IMPL, typename SUPERCLASS > -::cppu::IPropertyArrayHelper& SAL_CALL ODerivedDataType< CONCRETE_DATA_TYPE_IMPL, SUPERCLASS >::getInfoHelper() +::cppu::IPropertyArrayHelper& ODerivedDataType< CONCRETE_DATA_TYPE_IMPL, SUPERCLASS >::getInfoHelper() { if ( !m_bPropertiesRegistered ) { |