现在的位置: 首页 > 综合 > 正文

Schema in HiveMind

2013年06月29日 ⁄ 综合 ⁄ 共 2840字 ⁄ 字号 评论关闭

    支持自定义数据格式是HiveMind的又一大特色。通过<schema>元素,可以为配置扩展点,服务或拦截器的参数定值格式。而且随着HiveMind的自身发展,Schema所支持内容也会越来越丰富。现阶段schema仅支持对一系列element做处理,通过它可以把由它指定的xml文件片段解析成一个对象或对象的集合。
    HiveMind对schema的这种支持源于Apache开元项目Jarkata的一个子项目Digester。Digester是一种基于规则的XML解析技术,它以SAX接口为基础,但不同于DOM的解析方法。Digester不会将数据解析为某一种特殊的格式(如DOM的树形结构),而是产生一个规则集(规则是一元素路径为基础的),通过定制一些列规则生成一个对象或对象集。这个过程可以理解为XML到Object的映射过程。Tapestry3就是采用的这种技术对各类配置文件(*.application,*.jwc,*.page)进行解析的。Tapestry4和HiveMind中不再采用这种技术,但是它们使用的解析方式很多都是源于它。
    基于规则的XML解析可以理解为:规则=路径+处理;路径是XML出现的先后顺序,而处理是对对应路径的一个处理,由预先定义的一些列操作完成。在HiveMind里,<schema>可以包含多个<element>,<element>可以包含多个<attribute>,<element>, <rules> , <conversion>。<element>的name属性用于定义XML片段中出现的元素,<attribute>用于定义对应元素里面的属性。而<rules>和<conversion>都是用于定义规则的,<conversion>是<rules>的一个简化形式,用于处理最常见的几种操作。
    下面给出一个<schema>的简单例子:
<schema>
    <element name="person">
        <attribute name="name"/>
        <rules>
            <create-object class="com.csdn.hivemind.Person"/>
            <read-attribute attribute="name" property="personName"/>
            <invoke-parent method="addElement"/>
        </rules>
        <element name="habit">
            <attribute name="name"/>
            <rules>
                <create-object class="com.csdn.hivemind.Habit"/>
                <read-attribute attribute="name" property="habitName"/>
                <invoke-parent depth="1" method="addHabit"/>
            </rules>
        </element>
        <element name="profession">
            <attribute name="name"/>
            <rules>
                <create-object class="com.csdn.hivemind.Profession"/>
                <read-attribute attribute="name" property="professionName"/>
                <invoke-parent depth="1" method="addProfession"/>
            </rules>
        </element>
    </element>
</schema>
    上例给出了一个schema的简单例子,通过它可以解析如下的XML片段,并产生一个Person对象:
<person name="Hawk">
    <habit name="sports"/>
    <profession name="student"/>
</person>
    在读取需要解析XML数据的时候HiveMind会用一个处理器来完成这项工作。在处理之前schema和xml片段都会以树形形式保存在内存中,处理时处理器将这两项作为参数读入。整个处理的过程如下:schema in hivemind

    从图中可以看出整个处理的过程是一个递归的过程,首先读入一个xml的元素,找到schema中对应的元素并调用它所有的rule的begin方法。之后xml对象和schema同时往下走一层。XML再次找到一个节点habit,并从schema中找出对应的元素,调用rule的begin方法。此时habit没有子节点,不再递归下去,调用rule的end方法。同样的顺序处理profession元素,之后person的所有子节点处理完,调用它的rule的end方法。
    rule是一系列继承与统一接口的类,必须实现begin和end方法。不同的规则会决定在哪一个或两个方法中对元素的数据进行处理。值得注意的是同意个元素的规则begin调用的顺序和end调用的顺序是相反的。例如对于person元素调用begin的顺序是create-object,read-attribute,invoke-parent而调用end的顺寻是invoke-parent,read-attribute,create-object。这样做的目的主要是保证对于每一条rule的end方法,再它之前begin的rule都不会在它之前end。避免造成数据混乱。
    在处理schema时各条rule处理的结果在schema处理器中有一个栈负责保存。每一条create-object规则的begin方法都会往栈顶插入一个对象,并在end方法中弹出。schema处理器会将自身作为栈底元素首先方法栈中,所以根节点person的invoker-parent将会调用的是schema处理器的addElement方法。而habit和profession的<invoke-parent depth="1" method="..."/>规则调用的将是person的方法。
    在所有操作处理完之后,schema处理器将会放回由addElement方法加入的所有对象,默认为一个List。 

抱歉!评论已关闭.