forms/source/xforms/datatyperepository.cxx |    2 
 forms/source/xforms/datatypes.cxx          |  128 +++++++++++++++++++++++++++++
 forms/source/xforms/datatypes.hxx          |   29 ++++++
 3 files changed, 158 insertions(+), 1 deletion(-)

New commits:
commit d0ecc80ca4ab5fd19bf26dff8dc748c87444c024
Author:     Julien Nabet <serval2...@yahoo.fr>
AuthorDate: Sat Apr 22 21:19:06 2023 +0200
Commit:     Julien Nabet <serval2...@yahoo.fr>
CommitDate: Wed Apr 26 09:36:53 2023 +0200

    Related tdf#154769: XML forms add anyURI/hyperlink datatype
    
    See https://www.w3.org/TR/xmlschema11-2/#anyURI
    
    Since I copied-paste string datatype + add check url, I thought about 
deriving from string datatype
    but seeing 
https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/datatypes.html#built-in-datatypes
    anyURI doesn't derive from string
    
    TODO: contrary to "string" which uses "preserve" for "whitespace" "anyURI" 
uses "collapse"
    There's WhiteSpaceTreatment notion in datatypes.cxx and m_nWST associated,
    WhiteSpaceTreatment::Preserve seems to be the default but when searching 
about it, it's seems not used.
    
    Change-Id: Ifc2dc06072e40b9be168c2f40a9506fe7d267ce4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150822
    Tested-by: Jenkins
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>

diff --git a/forms/source/xforms/datatyperepository.cxx 
b/forms/source/xforms/datatyperepository.cxx
index fc446a5a3ecf..aba911c3f714 100644
--- a/forms/source/xforms/datatyperepository.cxx
+++ b/forms/source/xforms/datatyperepository.cxx
@@ -52,7 +52,7 @@ namespace xforms
         m_aRepository[ sName ] = new OStringType( sName, 
css::xsd::DataTypeClass::STRING );
 
         sName = ResourceManager::loadString(RID_STR_DATATYPE_URL);
-        m_aRepository[ sName ] = new OStringType( sName, 
css::xsd::DataTypeClass::anyURI );
+        m_aRepository[ sName ] = new OAnyURIType( sName, 
css::xsd::DataTypeClass::anyURI );
 
         sName = ResourceManager::loadString(RID_STR_DATATYPE_BOOLEAN);
         m_aRepository[ sName ] = new OBooleanType( sName );
diff --git a/forms/source/xforms/datatypes.cxx 
b/forms/source/xforms/datatypes.cxx
index 510e75cfd3d7..eb458ae925ba 100644
--- a/forms/source/xforms/datatypes.cxx
+++ b/forms/source/xforms/datatypes.cxx
@@ -24,6 +24,7 @@
 #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>
@@ -576,6 +577,133 @@ 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 )
     {
diff --git a/forms/source/xforms/datatypes.hxx 
b/forms/source/xforms/datatypes.hxx
index d640d566c83f..69d627403090 100644
--- a/forms/source/xforms/datatypes.hxx
+++ b/forms/source/xforms/datatypes.hxx
@@ -36,6 +36,8 @@
 
 #include <memory>
 
+#include <com/sun/star/util/URLTransformer.hpp>
+
 
 namespace xforms
 {
@@ -260,6 +262,33 @@ namespace xforms
         virtual void            registerProperties() override;
     };
 
+    class OAnyURIType;
+    typedef ODerivedDataType< OAnyURIType > OAnyURIType_Base;
+    class OAnyURIType   :public OAnyURIType_Base
+    {
+        // <properties>
+        css::uno::Any m_aLength;
+        css::uno::Any m_aMinLength;
+        css::uno::Any m_aMaxLength;
+        // </properties>
+        // helper to check URL validity
+        css::uno::Reference<css::util::XURLTransformer> m_xURLTransformer;
+
+    public:
+        OAnyURIType( const OUString& _rName, sal_Int16 _nTypeClass /* = 
css::xsd::DataTypeClass::anyURI */ );
+
+    protected:
+        virtual rtl::Reference<OXSDDataType> createClone(const OUString& 
_rName) const override;
+        virtual void initializeClone(const OXSDDataType& _rCloneSource) 
override;
+        void       initializeTypedClone( const OAnyURIType& _rCloneSource );
+
+        // OXSDDataType overridables
+        virtual TranslateId     _validate( const OUString& value ) override;
+        virtual OUString _explainInvalid( TranslateId rReason ) override;
+        virtual bool            checkPropertySanity( sal_Int32 _nHandle, const 
css::uno::Any& _rNewValue, OUString& _rErrorMessage ) override;
+        virtual void            registerProperties() override;
+    };
+
     class ODecimalType;
     typedef ODerivedDataType< ODecimalType, OValueLimitedType< double > > 
ODecimalType_Base;
     class ODecimalType : public ODecimalType_Base

Reply via email to