XWorker是动态系统,但其实其核心是X-Meta引擎,用Java虚拟机和Java程序来比喻,X-Meta引擎相当于Java虚拟机,而XWorker则是跑在虚拟机上的程序。
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>
X-Meta引擎中的事物是像XML这样结构的数据,由于XML几乎可以表达任何实体,所以X-Meta引擎中的事物也可以表达任何实体。
因此想要在X-Meta引擎中表示什么,比如表示一个对象、一个类或一个函数等,都是使用Thing这个对象来表示的。
事物本身可以用来表示实体,与实体对应的就是行为,即可以执行的程序,在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方法执行。
由于事物的结构和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);
我们知道在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变量了。
为了使用事物来表示类和对象的关系,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 "I am a Person, my name is ${self.name}";"></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);
为了能够高效的编写事物,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 "I am a Person, my name is ${self.name}";"></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-2014 XWorker.org 版权所有