MOQL--操作数(Operand) (三)

函数Operand

        函数Operand的格式如下:函数名(参数1,参数2…)。函数名与Java语法中标示符的命名规范一致,该命名规范已在变量Operand中进行了描述。其每一个参数都是一个OperandOperand可以是常量、变量、函数或者表达式中的任意一种。如:sum(a)_formatTime(‘yyyy-mm-dd’getCurrentTime())random(23+15)等。

          函数Operand的示例代码如下:

EntityMap entityMap = new EntityMapImpl();

entityMap.putEntity("num", 123);

try {

    Operand function = MoqlUtils.createOperand("max(num)");

    System.out.println(function.toString() + " " +  function.getOperandType());

    System.out.println(function.operate(entityMap));

    entityMap.putEntity("num", 345);

    System.out.println(function.operate(entityMap));

     //重置函数状态

    function.reset();

entityMap.putEntity("num", 12);

    System.out.println(function.operate(entityMap));

    function = MoqlUtils.createOperand("test(1, num, 'a')");

   System.out.println(function.toString() + " " +  function.getOperandType());

} catch (MoqlException e) {

e.printStackTrace();

}

其执行结果输出如下:

max(num) FUNCTION

123

345

12

test(1,num,'a')  FUNCTION

         MOQL目前已支持了部分的函数Operand,如聚集函数Operandcountsumavgmin、以及max等。这些Operand在生成后调用operate方法就可以直接对数据进行计算。但如果要创建一个MOQL未支持的函数,MOQL会为其创建一个缺省的Operand,该Operand只是对函数字符串进行了解析,如上面的代码片段中的函数“test(1, num, 'a')”。该函数字符串被解析为一个缺省的函数Operand,但是当我们调用它的operate方法时,它会抛出一个java.lang.UnsupportedOperationException,表示该Operand不支持该方法。为了能够让MOQL也支持test函数,我们需要为test做一个对应的Operand的实现。相关的实现代码如下:

publicclass TestRegistFunction {

    publicstaticclass Test extends AbstractFunction {

        public Test(List<Operand>  parameters) {

/* “test”是该对象对应的函数Operand的名字,3是test函数可以接受的参数数量。若parameters的size与该值不一样时,会抛出IllegalArgumentException,表示输入的函数字符串不合法*/

       super("test",3,parameters);

            functionType = FunctionType.COMMON;

        }

        @Override

        protected Object innerOperate(EntityMap  entityMap) {

            Object obj1 = parameters.get(0).operate(entityMap);

            Object obj2 = parameters.get(1).operate(entityMap);

            Object obj3 = parameters.get(2).operate(entityMap);

            StringBuffer sbuf = new StringBuffer();

            sbuf.append(obj1.toString());

            sbuf.append("||");

            sbuf.append(obj2.toString());

            sbuf.append("||");

            sbuf.append(obj3.toString());

            return sbuf.toString();

        }

    }

    publicstaticvoid main(String[] args) {

        EntityMap entityMap = new EntityMapImpl();

        entityMap.putEntity("num", 123);

        try {

            Operand function = MoqlUtils.createOperand("test(1, num, 'a')");

            System.out.println(function.toString() + " " +  function.getOperandType());

            System.out.println(function.operate(entityMap));

        } catch(Exception e) {

            e.printStackTrace();

        }

        try {

             //注册test函数的实现

            MoqlUtils.registFunction("test", Test.class.getName());

            Operand function = MoqlUtils.createOperand("test(1, num, 'a')");

            System.out.println(function.toString()  + " " + function.getOperandType());

            System.out.println(function.operate(entityMap));

        } catch (MoqlException e) {

            e.printStackTrace();

        }

    }

}

 

其执行结果输出如下:

test(1,num,'a')  FUNCTION

java.lang.UnsupportedOperationException

    at org.moql.operand.function.MemberFunction.innerOperate(MemberFunction.java:49)

    at org.moql.operand.function.AbstractFunction.operate(AbstractFunction.java:120)

    at org.moql.core.test.TestRegistFunction.main(TestRegistFunction.java:44)

test(1,num,'a')  FUNCTION

1||123||a

 

         Test类继承了AbstractFunction抽象类,它是test函数的Operand实现。test函数可以接收3个参数,当参数的个数与3不一致时,其构造函数将抛出异常,表示test函数的调用格式不正确,如:test(1,num)将会抛出异常。当我们定义一个函数其参数为变长时,我们可以将3替换为-1,表示变长。或者我们用org.moql.operand.function.Function中的VARIANT_PARAMETERS常量来表示,该值为-1Test类的主体逻辑在innerOperate中实现,Test类覆写了该方法,将三个参数简单的连接成一个字符串并返回。

从上例代码的执行情况我们看到,在第一次创建test函数的Operand后,调用operate方法抛出了异常;于是在第二次创建test函数的Operand前,我们调用了MOQL的函数注册方法,为test函数注册了Operand的实现类Test。而后我们创建了test函数的Operand并调用了它的operate方法。此次调用获得了预期的输出效果。其根本原因是,第一次创建的函数Operand,因未找到注册的Operand实现,生成了一个缺省的函数Operand,该Operand不支持operate方法;而第二次我们创建函数Operand时,发现了注册的实现类Test,于是绑定了该实现,生成了test函数对应的Operand。

项目地址:http://sourceforge.net/projects/moql/

                      代码路径:svn://svn.code.sf.net/p/moql/code/trunk

 

 

你可能感兴趣的:(Opera)