X-Meta引擎

1. X-Meta引擎和XWorker

    XWorker是动态系统,但其实其核心是X-Meta引擎,用Java虚拟机和Java程序来比喻,X-Meta引擎相当于Java虚拟机,而XWorker则是跑在虚拟机上的程序。

2. X-Meta引擎的基本概念

2.1 X-Meta引擎是一个数据解释引擎

    X-Meta引擎是一个解释引擎,它解释的对象是结构化的数据,X-Meta引擎是使用Java编写的,数据对应org.xmeta.Thing这个类,在X-Meta引擎中用事物来表示数据,Thing表示数据结构的代码如下:

package org.xmeta;

public class Thing{
    //属性
    protected Map<String, Object> attributes = new HashMap<String, Object>();

    //子节点
    protected List<Thing> childs = new CopyOnWriteArrayList<Thing>();
}

    从以上代码可以看出事物的结构是有属性和子节点事物构成的,即用Map保存属性,用List保存子节点,这个结构和XML类似,因此X-Meta引擎中的数据都可以转化为XML,比如一个简单窗口程序的XML代码:

<Shell name="shell" _xmeta_id_="" descriptors="xworker.swt.widgets.Shell" text="Transparent Shell"
              NO_TRIM="true" CLOSE="false"  TITLE="false" MIN="false" MAX="false" 
              width="400" height="300" NO_BACKGROUND="true" label="TranspanentShell">
    <AnimationGif gifPath="images/guide/mark/mark_large.gif"></AnimationGif>
    <Menu style="POP_UP">
        <MenuItem name="closeItem" text="退出">
            <listeners>
                <Listener>
                    <ShellNormalActions descriptors="xworker.swt.actions.ShellActions/@ShellNormalActions1"
                         shellName="shell"></ShellNormalActions>
                </Listener>
            </listeners>
        </MenuItem>
    </Menu>
    <DragMove>
        <actions></actions>
    </DragMove>
</Shell>

2.1.1 使用X-Meta引擎的数据可以表达任何实体

    X-Meta引擎中的事物是像XML这样结构的数据,由于XML几乎可以表达任何实体,所以X-Meta引擎中的事物也可以表达任何实体。

    因此想要在X-Meta引擎中表示什么,比如表示一个对象、一个类或一个函数等,都是使用Thing这个对象来表示的。

2.2 动作

    事物本身可以用来表示实体,与实体对应的就是行为,即可以执行的程序,在X-Meta引擎中事物有如下定义:

public class Thing{
      ....
      //事物可以转化为动作
      public Action getAtion();
      ......
}

    从代码上可以看到任何事物都可以转化为Action,Action是动作的意思,是可以执行的程序,比如:

//假设HelloWorld是一个数据
Thing helloWorld = World.getThing("HelloWorld");

//可以转化为动作
Action helloWorldAction = helloWorld.getAction();

//动作可以执行
helloWorldAction.run(actionContext); //actionContext是变量上下文

    假设HelloWorld是一个X-Meta引擎的可以解释执行的数据,那么它可以加载为Thing对象,进而可以转化为Action对象,然后可以通过run方法执行。

2.3 事物的行为

    由于事物的结构和XML的结构类似,可以包含子节点,而在2.2中任何事物都可以转化为动作,其中动作是可以执行的程序,因此可以用事物的子事物来定义它的行为。

<thing name="HttpDownloaderTest"  descriptors="xworker.lang.MetaDescriptor3" label="HttpDownloaderTest">
    <actions>
        <HttpDownloader name="run" descriptors="xworker.httpclient.actions.HttpDownloader" 
            filePath="e:/temp/http/" urls="http://news.sina.com.cn/w/zx/2015-11-04/doc-ifxkhcfq1111751.shtml">           
        </HttpDownloader>
    </actions>
</thing>

    如上面的代码的示例,X-Meta引擎约定第一个名为actions子节点下的子事物为它的行为的定义,比如上面HttpDownloaderTest这个事物具有一个名为run的行为,事物的行为调用代码如下:

//获取HttpDownlaoderTest
Thing thing = World.getInstance().getThing("HttpDownloaderTest");

//执行run方法
thing.doAction("run", actionContext);

2.3.1 self变量

    我们知道在Java里,如果一个对象调用自己的方法,那么在方法里可以直接访问this变量,其中this变量就是这个对象,同样在X-Meta引擎里self变量表示行为的所有者。

public class Thing{
     //doAction的实现示意代码
    public Object doAction(String name, ActionContext actionContext){
         //在acitons子节点下找对应名字的事物,或查找继承的动作事物(后面有解释)
        Thing actionThing = getActionThing(name);

        //转化为动作
        Action action = actionThing.getAction();

      //把自己作为self变量放入变量上下文
        actionContext.peek().put("self", this);

        //执行action
        action.run(actionContext);
    }
}

    在以上代码中doAction是事物调用自己的行为的方法,可以看到首先它找到表示行为的子事物,然后转化为动作,在调用前把自己作为self变量放到变量上下文中,这样动作内就可以访问self变量了。

2.3 事物之间的描述关系

    为了使用事物来表示类和对象的关系,X-Meta引擎定义事物之间的描述关系,如果一个事物A是事物B的描述者,那么事物B将继承事物A的行为。

    比如一个名为Person的事物:

<thing name="Person" descriptors="xworker.lang.MetaDescriptor3" label="Person">
    <attribute name="name" validateOnBlur="false" allowDecimals="false" allowNegative="false"></attribute>
    <attribute name="age" type="int" validateOnBlur="false" allowDecimals="false" allowNegative="false"></attribute>
    <thing name="Child" extends="xworker.example.otandoo.example.Person"></thing>
    <actions>
        <GroovyAction name="whoAmI" varScope="Global"
              code="return &quot;I am a Person, my name is ${self.name}&quot;;"></GroovyAction>
        <JavaAction name="sayHello" isSynchronized="false" useOuterJava="true" 
               outerClassName="test.Person" methodName="sayHello"></JavaAction>
    </actions>
</thing>

    它可以作为张三的描述者 ,其中描述关系用张三的descritpors属性来设置:

<Person name="Zhangsan" descriptors="Person" age="40" label="Zhangsan">
    <Child name="XiaoMing" age="10"></Child>
</Person>

    那么Zhangsan就有了Person的行为,比如:

//获取张三
Thing zhangsan = World.getInstance().getThing("zhangsan");

//执行sayHello
zhangsan.doAction("sayHello", actionContext);

2.4 事物之间的继承关系

    为了能够高效的编写事物,X-Meta引擎模也引入了继承关系,如果事物B继承了事物A,那么事物B将继承事物A的行为。

    同样以Person事物为例:

<thing name="Person" descriptors="xworker.lang.MetaDescriptor3" label="Person">
    <attribute name="name" validateOnBlur="false" allowDecimals="false" allowNegative="false"></attribute>
    <attribute name="age" type="int" validateOnBlur="false" allowDecimals="false" allowNegative="false"></attribute>
    <thing name="Child" extends="xworker.example.otandoo.example.Person"></thing>
    <actions>
        <GroovyAction name="whoAmI" varScope="Global"
              code="return &quot;I am a Person, my name is ${self.name}&quot;;"></GroovyAction>
        <JavaAction name="sayHello" isSynchronized="false" useOuterJava="true" 
               outerClassName="test.Person" methodName="sayHello"></JavaAction>
    </actions>
</thing>

    张三可以继承它从而拥有它的行为,其中继承关系用张三的extends属性来设置:

<Person name="Zhangsan" extends="Person" age="40" label="Zhangsan">
    <Child name="XiaoMing" age="10"></Child>
</Person>

    那么Zhangsan就有了Person的行为,比如:

//获取张三
Thing zhangsan = World.getInstance().getThing("zhangsan");

//执行sayHello
zhangsan.doAction("sayHello", actionContext);

    注意:在X-Meta引擎中继承并不实现属性和子事物的继承

Copyright ©  2007-2019 XWorker.org  版权所有  沪ICP备08000575号