• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Validation Customization:How to Implement Special Requirements with Custom Expressions? Extending Built-in Function Expressions


Does the platform provide many expressions, but they don't meet your scenario needs? How should we add new expressions to satisfy project requirements?

I. Scenarios for Extending Expressions

When needing to perform NULL validation on a specific parameter within a List-type field of input parameters, and finding that the platform's built-in functions cannot support configuration for this scenario, you can leverage the platform's relevant mechanisms to extend built-in functions.

Common code scenarios are as follows:

package pro.shushi.pamirs.demo.core.action;

......Imported classes

@Model.model(PetShopProxy.MODEL_MODEL)
@Component
public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> {

    @Override
    protected PetShopProxy fetchData(PetShopProxy data) {
        return data.queryById();
    }
    @Validation(ruleWithTips = {
        @Validation.Rule(value = "!IS_BLANK(data.code)", error = "Encoding is a required field"),
        @Validation.Rule(value = "LEN(data.name) < 128", error = "Name is too long, cannot exceed 128 characters"),
    })
    @Action(displayName = "Enable")
    @Action.Advanced(invisible="!(activeRecord.code !== undefined && !IS_BLANK(activeRecord.code))")
    public PetShopProxy dataStatusEnable(PetShopProxy data){
        data = super.dataStatusEnable(data);
        data.updateById();
        return data;
    }

    ......Other code

}

II. Creating a Custom Expression Function

A function for validating input parameters. When the input is a collection object, if a specific field of any single object in the collection is null, the function returns false.

Example:

Create a CustomCollectionFunctions class

package xxx.xxx.xxx;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.common.constants.NamespaceConstants;
import pro.shushi.pamirs.meta.util.FieldUtils;

import java.util.List;

import static pro.shushi.pamirs.meta.enmu.FunctionCategoryEnum.COLLECTION;
import static pro.shushi.pamirs.meta.enmu.FunctionLanguageEnum.JAVA;
import static pro.shushi.pamirs.meta.enmu.FunctionOpenEnum.LOCAL;
import static pro.shushi.pamirs.meta.enmu.FunctionSceneEnum.EXPRESSION;

/**
 * Custom built-in functions
 */
@Fun(NamespaceConstants.expression)
@Component
public class CustomCollectionFunctions {

    /**
     * LIST_FIELD_NULL is our custom expression, which must not repeat existing expressions!!!
     *
     * @param list
     * @param field
     * @return
     */
    @Function.Advanced(
        displayName = "Verify if the integrated parameter is null", language = JAVA,
        builtin = true, category = COLLECTION
    )
    @Function.fun("LIST_FIELD_NULL")
    @Function(name = "LIST_FIELD_NULL", scene = {EXPRESSION}, openLevel = LOCAL,
              summary = "Function example: LIST_FIELD_NULL(list,field). Function description: Pass an object collection to verify if the collection's field is null"
             )
    public Boolean listFieldNull(List list, String field) {
        if (null == list) {
            return false;
        }
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        for (Object data : list) {
            Object value = FieldUtils.getFieldValue(data, field);
            if (value == null) {
                return false;
            }
        }
        return true;
    }

}

III. Registering the Custom Expression Class to the Platform's Whitelist

Example:

Create the CustomFaasScriptAllowListApi class, where the @Order priority must be higher than the platform's default priority to take effect.

package xxx.xxx.xxx;

import org.apache.commons.collections4.SetUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.framework.faas.fun.builtin.*;
import pro.shushi.pamirs.framework.faas.spi.api.guard.FaasScriptAllowListApi;
import pro.shushi.pamirs.meta.common.constants.NamespaceConstants;
import pro.shushi.pamirs.meta.common.spi.SPI;

import java.util.Set;

/**
 * Custom implementation of SPI for function whitelist and blacklist allowing expression calls
 */
@Order(1) // Increase the priority of the custom class here
@Component
@SPI.Service
public class CustomFaasScriptAllowListApi implements FaasScriptAllowListApi {

    // Whitelist
    public static final Set<String> DEFAULT_SET = SetUtils.hashSet(

        // Whitelist, directly replicate the default implementation: pro.shushi.pamirs.framework.faas.spi.service.DefaultFaasScriptAllowListApi
        CollectionFunctions.class.getName(),
        ContextFunctions.class.getName(),
        DateFunctions.class.getName(),
        LogicFunctions.class.getName(),
        MapFunctions.class.getName(),
        MathFunctions.class.getName(),
        ObjectFunctions.class.getName(),
        RegexFunctions.class.getName(),
        TextFunctions.class.getName(),

        // Add your own whitelist classes below
        CustomCollectionFunctions.class.getName()

    );

    @Override
    public Set<String> classWhiteList() {
        return DEFAULT_SET;
    }

    @Override
    public Set<String> namespaceWhiteList() {
        return SetUtils.hashSet(NamespaceConstants.expression);
    }

}

IV. Using Custom Expressions

Example:

Demo usage scenario:

/**
     * Note: The [field] parameter of the custom function is a text, so quotes must be added to indicate the parameter is text; otherwise, data cannot be parsed. The same applies to other scenarios.
     *
     * @param data
     * @return
     */
@Action.Advanced(name = FunctionConstants.create, managed = true)
@Action(displayName = "Confirm", summary = "Create", bindingType = ViewTypeEnum.FORM)
@Function(name = FunctionConstants.create)
@Function.fun(FunctionConstants.create)
@Validation(ruleWithTips = {
    @Validation.Rule(value = "LIST_FIELD_NULL(data.itemAttributes,'itemId')", error = "Field cannot be empty"),
})
public DemoItem create(DemoItem data) {
return demoItemService.create(data);
}

Conclusion: You can leverage the platform's mechanisms to establish a set of expressions tailored to your specific scenario requirements.

Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Tree-Table Configuration:How to Configure Tree-Tables
Next
Process Extension:How to Add Workflow Runtime Dependencies
默认页脚
Copyright © 2026 Mr.Hope