• ofbiz 之minilang解析


    编写一个simple method 首先我们需要对输入参数进行验证 ,判断参数是否完整。 
    1. 验证 
    1.1. Login-required 
    :这是一个simple-method的属性,对是否需要登陆进行设置,默认值为true ,即默认需要先登陆。(加上service 定义中的auth 定义,所以如果你不希望一个simple service 必须登陆才能调用的话,那么首先得将service 定义中的auth设为false ,再将此处的login-required 设为false),后续会陆续多种子权限判断的用法,关于权限判断都是首先需要登陆的。 
    1.2. use-transaction 
    :设置此simple method 是否使用事务。根据业务需求来判断具体设置。 
    1.3. check-permission 
    :判断权限是否具有某一权限,一般用法为: 
    <check-permission permission="person" action="_update"> 
    <alt-permission permission="person" action="_view"/> 
    <fail-property resource="WebtoolsUiLabels" property="doNotHavePermission"></fail-property> 
    </check-permission> 
    <check-errors></check-errors> 
    使用check-permission前提条件是当前service 环境中必须存在用户的登陆信息,即能获取到userLogin . service 的调用场景有很多,controller.xml中,screen中,simple method 中,bsh文件中,ftl 文件中,java 文件中,groovy文件中等,其中前三项系统会自动将userLogin,locale 等信息自动封装到service context 中去,所以不需要我们手段传值,所以我们在其他环境中调用service的时候就需要对需要的隐性参数进行传值,比如fail-property中会用到locale, check-permission会用到userLogin 等,调用举例如下: 

    dispatcher.runSync("TestServiceOnSimple",UtilMisc.toMap("param3","TestServiceOnJava","userLogin",userLogin,"locale",locale)); //java文件中 

    check-permission中有个属性error-list-name="error_list" ,这条属性的意思是意义是将错误信息放到error_list这个list 中。配合check-errors的共同使用。 


    其中check-permission判断是否具有”${permission的值}_ADMIN” 权限,如果action的值不为null,则会首先判断当前用户是否具有”${permission的值}_ADMIN”权限,如果有则权限判定符合要求,否则判断是否具有”${permission的值}_${action的值}”,如果check-permission判断权限要求都不满足的话,会进行alt-permission 权限判断,判断规则和check-permission一样, check-permission 和 alt-permission 两者的关系是or的关系,即只要两者有一个满足权限要求即可。如果两者条件都不满足的话那么将会把fail-property 写进错误信息中,fail-property错误信息来源于”${ resource的值}.xml”中key值为”${property的值}”所对应的value 值。系统会自动根据客户端浏览器的locale从文件中获取对象的提示信息。 
    当然你也可以直接将来报错提示信息写在当前simple methord 中,使用 
    <check-permission permission="person" action="_update"> 
    <alt-permission permission="person" action="_view"/> 
    <fail-message message="you do not have XXX permission !!"/> 
    </check-permission> 
    fail-message 与 fail-property 是不能共存的,二者只能存其一。 
    所有上面的内容只会对权限进行判断,权限不满足的话收集提示信息,<check-errors></check-errors>则是返回错误信息。如果没有check-errors那么service method 将会继续往下执行。有check-errors的话则会中断simple method 的执行。 

    如果非要用java 语言进行翻译的话,我觉得应该是这样的。 

    <check-permission permission="person" action="_update"> 
    <alt-permission permission="party" action="_view"/> 
    <fail-property resource="WebtoolsUiLabels" property="doNotHavePermission"></fail-property> 
    </check-permission> 
    <check-errors></check-errors> 

    翻译成java service 应该是这样的. 

    Security security = dctx.getSecurity(); 
    if (!(security.hasPermission ("person_ADMIN", userLogin) 
    ||  security.hasPermission ("person_update", userLogin) 
    ||  security.hasPermission ("party_ADMIN", userLogin) 
    ||  security.hasPermission ("party_view ", userLogin)) 
    ) {Return ServiceUtil.returnError( 
    UtilProperties.getMessage("WebtoolsUiLabels","doNotHavePermission",locale)); 
    } 

    另:check-permission 中还有个子节点accept-userlogin-party ,似乎不很常用,后待研究 
    1.4. if-has-permission 
    <if-has-permission permission="person_view" > 
    <set field="hasPermission" type="Boolean" value="true"/> 
    <field-to-result field="hasPermission"/> 
    <log level="info" message="you have ACCTG_FX_ENTRY!"/> 
    <else> 
    <set field="hasPermission" type="Boolean" value="false"/> 
    <property-to-field 
    resource="CommonUiLabels" property="CommonGenericPermissionError" field="failMessage"/> 
    <field-to-result field="hasPermission"/> 
    <field-to-result field="failMessage"/> 
    </else> 
    </if-has-permission> 

    if-has-permission判断权限的规则和check-permission的规则是一样的。不重复了,if-has-permission和check-permission最大的不同在于if-has-permission可以进行if-else 的逻辑判断.当然如果不需要else判断的话可以把else节点整个去掉,即: 
    <if-has-permission permission="person_view" > 
    <set field="hasPermission" type="Boolean" value="true"/> 
    <field-to-result field="hasPermission"/> 
    <log level="info" message="you have ACCTG_FX_ENTRY!"/> 
    </if-has-permission> 


    翻译一下前边的if-has-permission的例子. 
    首先判断当前用户是否具有person_view的权限,如果有这个权限那么执行: 
    <set field="hasPermission" type="Boolean" value="true"/> 
    创建Boolean 变量 hasPermission 值为true 
    <field-to-result field="hasPermission"/> 
    将hasPermission这个变量赋值到result结果集中 
    <log level=" info" message="you have ACCTG_FX_ENTRY!"/> 
    输出info级别日志,” you have ACCTG_FX_ENTRY!”. 

    判断权限如果没有这个权限则执行: 

    <set field="hasPermission" type="Boolean" value="false"/> 
    创建Boolean 变量 hasPermission 值为false 
    <property-to-field 
    resource="CommonUiLabels" property="CommonGenericPermissionError" field="failMessage"/> 

    从CommonUiLabels.xml文件中获取key为CommonGenericPermissionError的国际化内容并赋值到变量failMessage中 
    <field-to-result field="hasPermission"/> 
    将hasPermission这个变量赋值到result结果集中 
    <field-to-result field="failMessage"/> 
    将failMessage这个变量赋值到result结果集中 

    1.5. if-compare 
    <if-compare field="statusId" 
    operator="equals" value="INVOICE_PAID"> 
             <log level="info" 
    message="The compare conditions are met"></log> 
             <else> 
             <log level="info" 
    message="The compare conditions are not met"></log> 
             </else> 
             </if-compare> 
    if-compare,把某一参数的值与一特定的值进行比较。比较的逻辑类型通过operator进行设置,种类主要有less,greater,less-equals,greater-equals,equals,not-equals,contains等,不挨个解释了无非是大于,等于,大(小)于等于,包含等。 
    if-compare中另外还有两个参数format、type . type指比较参数双方的数据类型,比较之前系统会将比较双方的参数转化成你指定的type类型。 
    format指比较参数双方的格式,一般用在日期格式中,和日期有关的type类型主要有Time,Date,Timestamp三种,针对这三种子日期类型format类型有三个默认值 
    分别是"HH:mm:ss","yyyy-MM-dd","yyyy-MM-dd HH:mm:ss.SSS" 。使用时间进行比较的时候参数的格式最好和默认的format相同,否则容易出现不可预料的问题。 

    与if-has-permission类似,当满足if条件的情况下执行<if-compare 与 <else>中间的内容,否则则执行<else>与</else>中间的内容,当然和if-has-permission一样,也可以不使用<else></else>(以后类似情况不再提了,自己类推吧。).即 
    <if-compare field="statusId" 
    operator="equals" value="INVOICE_PAID"> 
             <log level="info" 
    message="The compare conditions are met"></log> 
             </if-compare> 





    1.6. if-compare-field 
    if-compare-field与if-compare用法规则相同,唯一的不同在于if-compare是一个参数与固定值之间的比较,而if-compare-field是两个参数之间的比较。 
    1.7. if-empty 
    <if-empty field="param5"> 
        <log level="info" message="the parameter param5 is empty"></log> 
        <else> 
        <log level="info" message="the parameter is not empty "></log> 
        </else> 
    </if-empty> 

    判断一个参数是否为null,如上判断参数param5是否为null. 
    1.8. if-not-empty 
    <if-not-empty field="param5"> 
    <log level="info" message="the parameter is not empty "></log> 
    <else> 
        <log level="info" message="the parameter is empty "></log> 
    </else> 
    </if-not-empty> 
    顾名思义这个是和if-empty反着用的。 
       
    1.9. if-instance-of 
    <if-instance-of field="param5" class="String"> 
    <log level="info" message="the parameter is a String"></log> 
    <else> 
        <log level="info" message="the parameter is not a String"></log> 
    </else> 
    </ if-instance-of> 
    OR 
    <if-instance-of field="param5" class="java.util.List"> 
    <log level="info" message="the parameter is a List"></log> 
    <else> 
       <log level="info" message="the parameter is not a List"></log> 
    </else> 
    </if-instance-of> 
    if-instance-of判断某一参数是否属于指定的参数类型。类似于java 中的instanceof  。 

    1.10. if-regexp 
    <if-regexp field="param5" expr="^[a-zA-Z_0-9]+$"> 
    <log level="info" message="expr validate success"></log> 
    <else> 
    <log level="info" message="expr validate Fail"></log> 
    </else> 
    </if-regexp> 
    使用正则表达式对参数进行验证。 

    1.11. if-validate-method 
    <if-validate-method field="param5" method="isEmail"> 
    <log level="info" message="param5 is a Email"></log> 
    <else> 
    <log level="info" message=" param5 is not a Email"></log> 
    </else> 
    </if-validate-method> 

    使用验证方法对参数进行验证,if-validate-method有个class属性,其默认值为 
    "org.ofbiz.base.util.UtilValidate",使用${class}类中的${method}方法对参数param5进行验证。 
    1.12. if 
    <if> 
    <condition> 
    <and> 
    <if-compare field="param1" operator="equals" value="value1"/> 
    <if-compare field="param2" operator="equals" value="value2"/> 
    </and> 
    </condition> 
        <then> 
    <log level="info" message="condition1 validate success"></log> 
        </then> 
        <else-if> 
        <condition> 
    <if-compare field="param3" operator="equals" value="value3"/> 
    </condition> 
       <then> 
    <log level="info" message="condition2 validate success"></log> 
        </then> 
        </else-if> 
        <else> 
    <log level="info" message="condition1 and condition2 validate Fail"></log> 
        </else>
    </if>
    If 一般情况下配合condition 使用,进行多条件的组合判断,使用<and></and> 或者<or></or>组织多个条件的逻辑关系,如果condition 条件满足,那么执行then ,否则执行 else-if 或者 else . 此用法是minilang 中唯一可以使用else if 逻辑判断的地方。 
    1.13. check-id 
    <check-id field="parameters.orderId" error-list-name="error_list"> 
    </check-id> 
    对参数进行特殊字符验证,判断orderId 中是否含有空格、“、‘、&、?、<、>、、/等。针对每种不同的特殊字符,check-id 提供了一种默认错误提示信息与之对应,所以错误信息可以不用设置,当然也可以使用fail-message 和 fail-property提供错误信息(用法同check-permission ,后续用到将不再重复),将错误信息放到${error-list-name}中,供check-errors使用。 

        

    1.14. add-error 
    <add-error error-list-name="error_list"> 
        <fail-message message="error Need a reason?"/> 
    </add-error> 
    OR 
    <add-error error-list-name="error_list"> 
    <fail-property resource="WebtoolsUiLabels" property="errorKey"> 
    </fail-property>
    </add-error> 

    向一个错误结果list中添加错误信息,错误结果list的name 可以指定,错误信息的来源可以来自来源于国家化xml文件.而可以是直接写死的message。一般用在之前介绍的那么多if-XXXX判断中,如果条件不满足(<else></else>中间)那么将错误信息写入错误信息结果list中,再通过check-errors 将错误信息返回。 



    1.15. check-errors 
    <check-errors error-code="resultPage" error-list-name="error_list"> 
        </check-errors> 
    前边已经讲到很多,是将错误信息进行返回,如果错误信息结果${error-list-name}中存在错误那么将返回错误信息并终止当前simple method 的运行。 
    error-list-name指定要返回的错误信息结果list名称,MethodContext中可能会包含多个错误结果信息list,根据业务需要而定,  error-code 返回错误状态码,一般用在controller.xml 中, 
       <request-map uri="testServiceTest"> 
        <security https="false" auth="false"/> 
            <event type="service" invoke="TestServiceOnJava"/> 
    <response name="success" type="view" value="toSuccess"/> 
            <response name="error"   type="view" value="toError"/> 
    <response name="resultPage"   type="view" value="toResult"/> 
       </request-map> 
    系统会根据其返回的code 而指向不同的request 或者 view 。 

    check-errors 另有4个节点,(已过期,源码已经被注释) 
    <message-suffix resource="WebtoolsUiLabels" property="doNotHavePermission2"></message-suffix> 
    <message-prefix resource="WebtoolsUiLabels" property="doNotHavePermission2"></message-prefix> 
    <error-prefix   resource="WebtoolsUiLabels" property="doNotHavePermission2"></error-prefix> 
    <error-suffix   resource="WebtoolsUiLabels" property="doNotHavePermission2"></error-suffix> 
    1.16. assert 
    assert:断言待确定。 

    calculate 
    1.17. calculate 
    calculate:待确定 


    2. 数据操作 
    2.1. clone-value 
    <clone-value value-field="lookedUpValue" new-value-field="newLookedUpValue"/> 
    clone-value克隆参数。以${value-field}参数对象为模板,创建一个新的参数对象。value-field的值必须是一个GenericValue对象或者是能够转化成GenericValue的对象。 
    2.2. clear-field 
    <if-not-empty field="param6"> 
    <log level="info" message="the value of  param6 is not empty"></log> 
       </if-not-empty> 
        <clear-field field="param6"/> 
        <if-empty field="param6"> 
    <log level="info" message="the value of  param6 is empty"></log> 
    </if-empty> 
    运行结果 
    [CommonServices.xml#TestServiceOnSimple line 85] the value of  param6 is not empty 
    [CommonServices.xml#TestServiceOnSimple line 89] the value of  param6 is empty 
    clear-field 将参数${field}从simple method 运行环境中methodContext清除掉。 
    2.3. create-object 
    待确定 
    2.4. clear-cache-line 
    待确定 

    2.5. clear-entity-caches 
    待确定 

    2.6. entity-one 
    <set field="UserLogin" value="admin"/> 
    <entity-one entity-name="UserLogin" value-field="adminUserLogin" 
    auto-field-map="true" use-cache="true"> 
    </entity-one> 
    <log level="info" message="${adminUserLogin}"></log> 
    entity-one根据给定主键对某一特定实体进行主键查询。如上例:根据实体UserLogin 主键userLoginId的值进行主键查询,并将查询结果定义为adminUserLogin。 
    由于entity-one 的属性auto-field-map的值设置为true,所以系统会从simple method 的运行环境MethodContext中自动寻找实体的主键。use-cache 是关于是否首 先从缓存中获取数据的设置。 

    如果auto-field-map的值设置为false,那么系统将不会自动从封装实体主键,那么需要我们手动给参,如下: 
    <entity-one entity-name="UserLogin" value-field=" adminUserLogin " auto-field-map="false"> 
    <field-map field-name="userLoginId" value="admin"/> 
    </entity-one>
    <set field="userLoginId" value="admin"/> 即为给主键传参。参数可以为固定的value 值,也可为已经存在与运行环境中的参数值。如下: 
    <set field="userLoginId" value="admin"/> 
    <entity-one entity-name="UserLogin" value-field=" adminUserLogin " auto-field-map="true"> 
       <field-map field-name="userLoginId" from-field=" userLoginId "/> 
       <select-field field-name="currentPassword"/> 
       <select-field field-name="disabledDateTime"/> 
    </entity-one> 
    select-field为非主键选择性输出,即将实体字段中用到的字段写入查询结果adminUserLogin中,用不到的则不写入。select-field 不得设置主键,且使用select-field时不能与use-cache="true" 同时使用。 
    2.7. entity-and 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
            <field-map field-name="partyId" value="admin"/> 
            <select-field field-name="workEffortId"/> 
            <order-by field-name="+workEffortId"/> 
    </entity-and> 
    <log level="info" message="${wepaList}"></log> 

    entity-and 非主键多条件查询。 
    use-cache 是关于是否首先从缓存中获取数据的设置。不能和select-field共同使用。 

    为了容易查看效果这里使用select-field(用法同entity-one 中select-field)限制查询字段只显示输出了workEffortId
    字段。输出结果如下: 
    { 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9000(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9002(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9100(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,CALENDAR_PUB_DEMO(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,OneOffMeeting(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,STAFF_MTG(java.lang.String)] 
    } 
    entity-and 中属性 limit-range 效果展示 : 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
    <field-map field-name="partyId" value="admin"/> 
        <select-field field-name="workEffortId"/> 
        <order-by field-name="+workEffortId"/> 
        <limit-range size="3" start="2"/> 
    </entity-and> 
    <log level="info" message="${wepaList}"></log> 
    输出结果: 
    { 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9002(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9100(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,CALENDAR_PUB_DEMO(java.lang.String)] 
    } 
    可以发现limit-range的功能为截取查询结果,从第${start}(包括此条)数据起,截取${size}条数据做为最终结果。 

    entity-and 中属性 limit-view 效果展示 : 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
    <field-map field-name="partyId" value="admin"/> 
        <select-field field-name="workEffortId"/> 
        <order-by field-name="+workEffortId"/> 
        <limit-view view-size="2" view-index="2"/> 
    </entity-and> 
    <log level="info" message="${wepaList}"></log> 
    输出结果: 
    { 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,9100(java.lang.String)], 
    [GenericEntity:WorkEffortPartyAssignment][workEffortId,CALENDAR_PUB_DEMO(java.lang.String)] 
    } 
    可以发现limit-view 类似于分页,将查询结果划分为每页${view-size}条数据,取第${view-index}页数据,如果用limit-view 来实现相同功能的话,需要设置start="3",size="2" 

    entity-and 中属性 use-iterator 效果展示 : 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
    <field-map field-name="partyId" value="admin"/> 
        <select-field field-name="workEffortId"/> 
        <order-by field-name="+workEffortId"/> 
        <use-iterator/> 
    </entity-and> 
    <if-instance-of ass="org.ofbiz.entity.util.EntityListIterator" 
    ield="wepaList"> 
    <log level="info" message="the wepaList is a Iterator"></log> 
    </if-instance-of> 
    <if-instance-of class="java.util.List" field="wepaList"> 
    <log level="info" message="the wepaList is a List object"></log> 
    </if-instance-of> 
    设置<use-iterator/>时输出结果为: 
    the wepaList is a Iterator 
    不设置时输出结果为: 
    the wepaList is a List object 
    可见设置<use-iterator/>使输出参数结果的格式发生了变化。如果设置了use-iterator ,却不使用EntityListIterator结果对象的话,会报错(待查验) 
    总结:use-iterator、limit-view、limit-range 三者不能两两共存,且此三者所处位置必须在其他同级节点的后面。 
    2.8. entity-condition 
    <entity-condition list="partyAssignments" entity-name="WorkEffortPartyAssignment" filter-by-date="true"> 
        <condition-list combine="and"> 
        <condition-expr field-name="workEffortId" from-field="workEffortId"/> 
        <condition-expr field-name="partyId" from-field="userLogin.partyId"/> 
        <condition-expr field-name="statusId" value="PRTYASGN_ASSIGNED"/> 
      <condition-list combine="or"> 
        <condition-expr field-name="roleTypeId" value="CAL_OWNER"/> 
        <condition-expr field-name="roleTypeId" value="CAL_ORGANIZER"/> 
        <condition-expr field-name="roleTypeId" value="CAL_DELEGATE"/> 
        </condition-list> 
        </condition-list> 
    </entity-condition> 
    entity-condition 对实体${entity-name}进行多条件组合逻辑查询。 
    ofbiz 很多实体在创建的时候都会有两个字段,分别为fromDate 和 thruDate. 
    这两个字段一般被用来代表当前数据的有效期间,既当前数据的有效期为大于等于fromDate 且  小于 thruDate 。 当fromDate 为null 时 则表示前端无限制, thruDate表示后端无限制。 
    属性distinct很好理解,剔除重复数据。需要注意的是如果配合select-field 共同使用的时候,判断重复的条件是判断select-field 需要显示字段是否重复,而不是判断当前实体所有的字段,即SQL 执行顺序是 先select-field 再distinct。 
    属性filter-by-date即为对记录表数据时间有效性的过滤,使用前提是当前实体必须有fromDate 和 thruDate这两个字段,且不能使用缓存进行查询 ,即use-cache="false",转化成sql 表示为 
    ((thruDate IS NULL OR thruDate > '当前时间') AND (fromDate IS NULL OR fromDate <= '当前时间')) 

    condition-expr为单个条件的逻辑判断,逻辑判断类型通过operator 进行设置,用法和if-compare类似。ignore-if-empty="true",当前字段为“”时是否忽略, 
    意思是如果当前进行判断的字段为””则忽略此判断。同理ignore-if-null="true"意思是如果当前进行判断的字段为null则忽略此判断. 

    condition-list为多个条件的逻辑组合,通过combine对condition-list节点中的多个condition-expr 进行逻辑组合,逻辑关系主要有 “and” 和 “or” 两种。 

    condition-object为使用当前simple 运行环境中已经存在的org.ofbiz.entity.condition.EntityCondition 类型的对象进行逻辑判断。 

    having-condition-list一般用于带有group-by 查询的视图实体查询,首先对根据condition-list查询条件进行查询,然后再根据having-condition-list查询条件进行限制查询。 比如: 
    <view-entity entity-name="WorkEffortPartyAssignmentView" package-name="org.ofbiz.workeffort.workeffort"> 
      <member-entity entity-alias="wepa" entity-name="WorkEffortPartyAssignment"></member-entity> 
    <alias-all entity-alias="wepa"> 
      <exclude field="partyId"/> 
      </alias-all>
      <alias entity-alias="wepa" name="partyId" group-by="true"> 
      </alias> 
      <alias entity-alias="wepa" name="quantityTotal" field="partyId" function="count"/> 
    </view-entity> 
    此视图实体全部使用WorkEffortPartyAssignment的参数,根据partyId进行分组,然后获取每组的数量。 
    查询使用: 
    <entity-condition list="wepaListTwo" entity-name="WorkEffortPartyAssignmentView"> 
    <condition-list combine="or"> 
    <condition-expr field-name="partyId" operator="equals" value="admin"/> 
    <condition-expr field-name="partyId" operator="equals" value="DemoEmployee2"/> 
    <condition-expr field-name="partyId" operator="equals" value="DemoEmployee3"/> 
    </condition-list> 
    <having-condition-list> 
    <condition-expr field-name="quantityTotal" operator="equals" value="3"/> 
    </having-condition-list> 
    <select-field field-name="partyId"/> 
    <select-field field-name="quantityTotal"/> 
    <use-iterator/> 
    </entity-condition> 
    首先根据三个partyId条件进行逻辑或进行分组查询,然后再对查询结果进行having-condition-list筛选。Sql 解析结果为: 
    SELECT wepa.PARTY_ID, COUNT(wepa.PARTY_ID) FROM OFBIZ.WORK_EFFORT_PARTY_ASSIGNMENT wepa WHERE ((wepa.PARTY_ID = 'admin' OR wepa.PARTY_ID = 'DemoEmployee3' OR wepa.PARTY_ID = 'DemoEmployee2')) GROUP BY wepa.PARTY_ID HAVING (COUNT(wepa.PARTY_ID) = 3) 
    having-condition-list 用法同condition-list。 
    总结:entity-condition当使用缓存进行查询时,不能使用distinct、having-condition-list、select-field。entity-condition查询限制条件最外层必须为condition-list、condition-expr、condition-object中的一个,三者不能两两并存。entity-condition的几个子节点配置先后顺序分别为:[condition-list、condition-expr、condition-object]三者中的一个、[having-condition-list]、[select-field],[order-by]、[use-iterator、limit-view、limit-range]三者中的一个。


    2.9. entity-count 
    <entity-count count-field="num" entity-name="WorkEffortPartyAssignment"> 
    <condition-list combine="or"> 
    <condition-expr field-name="partyId" operator="equals" value="admin"/> 
    <condition-expr field-name="partyId" operator="equals" value="DemoEmployee2"/> 
    <condition-expr field-name="partyId" operator="equals" value="DemoEmployee3"/> 
    </condition-list> 
    </entity-count> 
    entity-count 查询${entity-name}中符合条件的数据条数并赋值到 ${count-field}参数。条件配置与 entity-condition 一样。不罗嗦。 
    2.10. entity-data 
    待确定 
    2.11. find-by-primary-key 

    <set field="fieldsToSelect[]"   value="currentPassword"/> 
    <set field="fieldsToSelect[]"   value="partyId"/> 
    <set field="inParma.userLoginId" value="admin"/> 
    <!—- 此处以上都是参数的处理以及设置 --> 
    <find-by-primary-key entity-name="UserLogin" value-field="outResult" map="inParma" fields-to-select-list="fieldsToSelect" /> 
    <log level="info" message="---${outResult}---"></log> 
    find-by-primary-key功能与entity-one 相同,不同的是find-by-primary-key需要将主键字段封装到一个map中,然后使用,显示字段slelect-field 也是需要先将需要显示的字段封装到一个list 中。 
    : entity-name:查询实体名称。 
    :value-field:查询结果得到的实体对象名称。 
    :map: 一个map ,其中包含了主键字段。作为主要查询的依据。如果主键由多个字段组合而成,那么此map中需要包含所有的主键的字段信息。 
    :fields-to-select-list: 一个list,配置查询结果中所包含的非主键字段,主键字段就不要再这里设置了。 
    :use-cache:与entity-one 不同,这里的use-cache可以和选择性显示字段fields-to-select-list共同使用 
    2.12. find-by-and 
    <clear-field field="inParma"/> 

    <set field="inParma.partyId" value="admin"/> 
    <set field="orderList[]" value="+partyId"/> 
    <set field="orderList[]" value="-workEffortId"/> 


    <find-by-and list="outResult" map="inParma" entity-name="WorkEffortPartyAssignment" order-by-list="orderList" use-cache="true" use-iterator="true"/> 
    <iterate entry="out" list="outResult"> 
    <log level="info" message="iterator---${out}---"></log> 
    </iterate> 
    功能同entity-and,多条件查询。 

    :map:map 类型,其中放置了查询条件,map中多条查询条件之间的逻辑关系是and的关系。由于输入参数inParma这个map不能包含所查询实体${entity-name}之外的字段,在之前程序中我们可能已经使用过这个inParma参数,其中可能已经包含一些其他数据,所以我们使用之前最好将inParma参数清除一下。即<clear-field field="inParma"/> 
    :order-by-list:list 类型,排序的依据。需要提前封装。 
    :use-cache:是否使用缓存查询,与entity-and中use-cache会与其他节点或者属性有冲突不同,这里use-cache与其他节点属性可以共存。 
    :use-iterator:是否使用iterator类型返回参数。 
    2.13. get-related-one 
    <make-value value-field="userNew" entity-name="UserLogin"/> 
    <set field="userNew.partyId" value="admin"/> 
    <get-related-one relation-name="Party" to-value-field="partyNew" value-field="userNew"/>

    get-related-one根据外键实体获取外键所对应主键的实体。 
    实体与实体之间存在一中relation关系,如果把relation的方称为 甲实体 ,被relation的实体称为乙实体 。那么这里是根据 甲实体对象对乙方实体对象进行业务操作(查询)。使用get-related-one的前提是 甲实体 对乙方实体 relation 的type类型为one 或者 one-noFK 。 
    :value-field:甲方实体对象名称,查询依据。此实体必须包含relation 字段的值, 
    即甲方实体对象相对应乙方的外键值必须不能为null值。否则获得结果集为null; 
    :relation-name:查询实体名称。 
    :to-value-field:查询结果实体对象名称。 


    后面将会介绍到remove-related ,这个和 get-related-one 的关系有点相反。 
    remove-related 是根据乙方实体对象对甲方实体对象进行业务操作(删除)。 
    把这两个结合起来看吧 。(相关relation 的操作建议熟悉实体的relation 再看) 

    2.14. get-related 
    <clear-field field="partyNew"/> 
    <make-value value-field="partyNew" entity-name="Party"/> 
    <set field="partyNew.partyId" value="AUTHOR_MADMAX"/> 
    <get-related relation-name="UserLogin" list="userLoginList" value-field="partyNew"/> 
    待定。。。。。。 


    2.15. filter-list-by-and 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
    <field-map field-name="partyId" value="admin"/> 
    <select-field field-name="workEffortId"/> 
    <select-field field-name="partyId"/> 
    <select-field field-name="roleTypeId"/> 
    <order-by field-name="+workEffortId"/> 
    </entity-and> 
    <iterate entry="wepaL" list="wepaList"> 
    <log level="info" message="before filter --- ${wepaL}"></log> 
    </iterate> 

    <clear-field field="inParma"/> 
    <set field="inParma.workEffortId" value="9000"/>
    <set field="inParma.roleTypeId" value="PROVIDER_MANAGER"/> 

    <filter-list-by-and list="wepaList" map="inParma" to-list="wepaListFilter"/> 
    <iterate entry="wepa" list="wepaList"> 
    <log level="info" message="after filter wepaList --- ${wepa}"></log> 
    </iterate> 
    <iterate entry="wepa" list="wepaListFilter"> 
    <log level="info" message="after filter wepaListFilter----${wepa}"></log> 
    </iterate> 
    输出结果如下: 
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9000(java.lang.String)]                 
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9002(java.lang.String)]                 
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9100(java.lang.String)]                 
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_OWNER(java.lang.String)][workEffortId,CALENDAR_PUB_DEMO(java.lang.String)]           
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_ATTENDEE(java.lang.String)][workEffortId,OneOffMeeting(java.lang.String)]            
    before filter --- [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_ATTENDEE(java.lang.String)][workEffortId,STAFF_MTG(java.lang.String)]                
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9000(java.lang.String)]      
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9002(java.lang.String)]      
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9100(java.lang.String)]      
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_OWNER(java.lang.String)][workEffortId,CALENDAR_PUB_DEMO(java.lang.String)] 
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_ATTENDEE(java.lang.String)][workEffortId,OneOffMeeting(java.lang.String)] 
    after filter wepaList ---    [GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,CAL_ATTENDEE(java.lang.String)][workEffortId,STAFF_MTG(java.lang.String)]     
    after filter    wepaListFilter----[GenericEntity:WorkEffortPartyAssignment][partyId,admin(java.lang.String)][roleTypeId,PROVIDER_MANAGER(java.lang.String)][workEffortId,9000(java.lang.String)] 

    filter-list-by-and 的功能为对存放GenericValue对象的list ,使用一个存放有一个或者多个list 中GenericValue对象的字段的键值对,对list进行筛选。 
    如果list中GenericValue对象的字段能够和map中的对象(map中多个对象关系为and,必须全部满足。)对应起来那么则满足条件。 
    <filter-list-by-and list="wepaList" map="inParma" to-list="wepaListFilter"/> 
    如果 to-list有值,那么则过滤后的结果放到${to-list}中去,否则过滤后结果覆盖${to-list}. 
    Map中key 值必须为list 中GenericValue对象中存在的字段,否则过滤后结果为null。 
    2.16. filter-list-by-date 
    <entity-and entity-name="WorkEffortPartyAssignment" list="wepaList"> 
    <field-map field-name="partyId" value="admin"/> 
    <order-by field-name="+workEffortId"/> 
    </entity-and> 
    <set field="DateNow" type="Timestamp" value="2009-07-04 10:53:25.546"/> 
    <filter-list-by-date list="wepaList" to-list="wepaListFilter" all-same="false" from-field-name="fromDate" thru-field-name="thruDate" valid-date="DateNow"/> 
    <iterate entry="wepa" list="wepaList"> 
    <log level="info" message="after filter wepaList --- ${wepa}"></log> 
    </iterate> 
    <iterate entry="wepa" list="wepaListFilter"> 
    <log level="info" message="after filter wepaListFilter----${wepa}"></log> 
    </iterate> 
    filter-list-by-date 对含有GenericValue对象的list 集合中数据进行时间有效性验证。 
    :list:要进行过滤验证的list 的名称.其中包含对象必须为GenericValue对象. 
    : to-list:过滤后结果输出集合名称,如果不设置此值,结果会覆盖输入集合。 
    :from-field-name:时间有效性验证开始时间字段。 
    :thru-field-name:时间有效性验证结束时间字段。 
    :all-same:无效字段。 
    :valid-date:时间有效性验证的标准,此值必须是一个在运行环境中存在的时间类型的参数。如果不设置此值,默认使用当前时间。炎症规则请参考 entity-condition 的filter-by-date。 
    2.17. make-value 
    <clear-field field="inParma"/> 
    <set field="inParma.userLoginId" value="djtao"/> 
    <make-value value-field="user" entity-name="UserLogin" map="inParma"/> 
    <log level="info" message="make-value----${user}"></log> 
    输出结果: make-value----[GenericEntity:UserLogin][userLoginId,djtao(java.la ng.String)] 
    Make-value : 创建一个GenericValue对象. entity-name是所要创建对象的实体的名称,value-field是所创建对象的参数名称, map会将其中自动与实体字段相对应的值赋到实体对象中。 
    2.18. set-pk-fields 
    <clear-field field="inParma"/> 
    <set field="inParma.partyId" value="admin"/> 

    <set-pk-fields value-field="wepaNew" set-if-null="true" map="inParma"/> 

    set-pk-fields 用于给一个GenericValue对象 赋主键值。如果${map}参数中所包含的内容中key有GenericValue对象主键的字段相同的,那么将此key所对象的value赋到GenericValue对象。 
    :value-field:GenericValue对象 名称。将要被赋予值的参数名称。 
    :map:主键值来源。 
    :set-if-null:其目的是想如果map 中某主键对应的值为null的话,是否对此主键进行赋值,如果此设置为“true”的话,主键对应的值为null 或者 “”的话,程序都会给此主键赋值为null 。如果此如果此设置为“false”的话,null值则会忽略,其他原样赋值。 

    2.19. set-nonpk-fiels 
    <set-nonpk-fields value-field="wepaNew" map="inParma" set-if-null="true"/> 
    给非主键赋值,规则和set-pk-fields一样 不重复。 




    2.20. create-value 
    <create-value value-field="wepaNew" do-cache-clear="true" or-store="false"/> 

    在经过make-value、set-pk-fields、set-nonpk-fields之后一个完整的实体对象 就被创建起来了,那么我们将使用create-value将这个实体对象保存到数据库中。 

    :value-field:要保存对象的名称。 
    :do-cache-clear:清除缓存。 
    :or-store:如果数据库中已存在此主键对应数据,是否根据实体对数据进行update更新。 
    2.21. store-value 

    <set field="user.currentPassword" value="321"/> 

    <store-value value-field="user" do-cache-clear="true"/> 

    解析后执行SQL 
    UPDATE OFBIZ.USER_LOGIN SET CURRENT_PASSWORD=?, LAST_UPDATED_TX_STAMP=?, LAST_UPDATED_STAMP=? WHERE USER_LOGIN_ID=?

    minilang 中更新数据和我们用SQL 直接更新不同。首先我们必须获得包含主键信息的实体对象,这个获取实体对象的方式可以是我们用make-value手动生成,也可以根据主键信息查询数据得到的实体对象,然后对实体对象中字段进行set修改。然后使用store-value就可以将改动些到数据库中了。Update 字段只修改实体对象中的非主键字段。 
    :do-cache-clear:清除缓存。 

    2.22. store-list 
    <set field="listUser[]" from-field="user"   /> 
    <set field="listUser[]" from-field="user"   /> 
    <set field="listUser[]" from-field="user"   /> 
    <set field="listUser[]" from-field="user"   /> 
    <set field="listUser[]" from-field="user"   /> 

    <store-list list="listUser" do-cache-clear="true"/> 

    store-list批量修改数据。${list}是一个list 其中放的是要被写入数据库的实体对象。 
    store-list 与 store-value 不同的地方在于 , 如果store-list 中的实体对象在数据库中不存在时,他会首先创建一条记录,而store-value 却不会。 

    2.23. remove-value 
    <remove-value value-field="user" do-cache-clear="true"/> 
    根据包含主键字段的实体删除数据。 


    2.24. remove-list 
    <remove-list list="listUser" do-cache-clear="true"/> 

    批量删除。将一个包含多个实体对象的list 中所代表的数据行全部删除。 



    2.25. remove-by-and 
    <set field="whereMap.partyId" value="djtao"/> 
    <set field="whereMap.userLoginId" value="djtao"/> 
    <set field="whereMap.currentPassword" value="djtao"/> 
    <remove-by-and map="whereMap" entity-name="UserLogin" do-cache-clear="true"/> 
    SQL解析后结果为: 
    DELETE FROM OFBIZ.USER_LOGIN WHERE (PARTY_ID = 'djtao' AND USER_LOGIN_ID = 'djtao' AND CURRENT_PASSWORD = 'djtao') 
    根据多条条件删除实体数据。Map中各个条件之间逻辑关系为and 关系。 

    2.26. remove-related 
    <make-value value-field="partyObject" entity-name="Party"/> 
    <set field="inMap.partyId" value="djtao"/> 
    <set-pk-fields value-field="partyObject" map="inMap"/> 

    <remove-related relation-name="UserLogin" value-field="partyObject"/> 
    SQL解析后结果为: 
    DELETE FROM OFBIZ.USER_LOGIN WHERE (PARTY_ID = 'djtao') 

    remove-related 根据外键所对应主键的实体的对象删除外键实体记录。如上例:UserLogin 实体中,partyId为外键,根据外键的实体对象进行删除。 



    2.27. sequenced-id 
    <make-value value-field="newEntity" entity-name="WorkEffort"/> 

        <sequenced-id sequence-name="WorkEffort" field="workEffortId"/> 
    <set field="newEntity.workEffortId" from-field="workEffortId"/> 
    sequenced-id 一般用于获取实体的自增长字段。 
    :sequence-name:实体名称。 
    :field:获取到的自增长字段值的名称。 
    :get-long-only:待确定。 
    :stagger-max:待确定。 
    当然也可以这样用,可以节省一行代码,如下: 
    <make-value value-field="newEntity" entity-name="WorkEffort"/> 
    <sequenced-id sequence-name="WorkEffort" field="newEntity.workEffortId"/> 
    2.28. make-next-seq-id(待验证) 
    <make-value value-field="newEntity" entity-name="WorkEffort"/> 
       <make-next-seq-id seq-field-name="workEffortId" value-field="newEntity"/> 
    功能和sequenced-id 差不多,但由于其自增长字段是通过程序获得并写入数据库的方法获得的,所以在高并发或者一次获取多条自增长的情况下,自增长的值可能会重复。但似乎sequenced-id能避免此问题,待验证。 
    :value-field:想要获得自增长字段的实体对象。 
    :seq-field-name:实体的自增长字段。 
    :increment-by:待确定 
    :numeric-padding:待确定
    3. 逻辑操作 
    3.1. set 
    <set field="inMap.num" value="2"/> 
    <set field="newValue" default-value="1" from-field="inMap.num" set-if-empty="true" set-if-null="true" type="String"/> 
    Set 为变量参数赋值 。 
    : field: 变量参数的名称. 
    : from-field:变量参数值来源来源于环境中已经存在的变量.当然也可以使用value 
    赋固定值。 
    :default-value:默认值,当from-field和value都不存在时,使用默认值。 
    :set-if-empty:如果变量的值为””是否仍然赋””于变量。 
    :set-if-null:如果变量的值为null,是否仍然赋变量null。所以如果此属性配置为false(默认为false) 的话,那么使用set 的话,如果不赋值那么此set 无效。如: 
    <set field="inMap.num" />此行代码无任何意义。 

    3.2. set-calendar 
    创建calendar 日期对象,待确定。 
    3.3. set-current-user-login 
    <set field="ulLookup.userLoginId" value="system"/> 
      <find-by-primary-key entity-name="UserLogin" map="ulLookup" value-field="newuserLogin"/> 

    <set-current-user-login value-field=" newuserLogin"/> 
    <log level="info" message="${parameters.userLogin}"></log> 
    <log level="info" message="${userLogin}"></log> 

    set-current-user-login 改变当前simple context 中的userLogin . 
    parameters中的userLogin 不发生改变。 
    3.4. string-append 
    <string-append string="456" field="newString" arg-list="newList"  prefix="prefix" suffix="suffix"/> 
    将String 字符串拼接起来。 
    效果类似于 : 
    newString = “${newString}”+”${prefix}”+”${string}”+”${suffix}” 
    :arg-list:待确定 

    3.5. string-to-list 
    <set field="newList" type="List"/> 
       <string-to-list string="a" list="newList"/> 
       <string-to-list string="b" list="newList"/> 
       将字符串放到一个list 中。 
    3.6. session-to-field 
    <session-to-field field="sessionField" session-name="_WEBAPP_NAME_" default="sessionNull"/> 
    Session-to-field 将session 中参数取出来赋值到当前环境的某变量中。 
    :field:变量名称. 
    :session-name:session中变量的名称. 
    : default:如果sesssion 中此变量对应的值为null的话,则使用此默认值。 
    注:此命令只有在event 调用simple  method 时方有效。即(MethodContext. methodType== MethodContext.EVENT)时方可使用。 
    目前所知符合条件的只有一种情况,即在controller.xml中,如下例。 
    <request-map uri="testServiceDelegator"> 
       <event type="simple" 
    invoke="TestServiceOnSimple" path="component://webtools/script/org/ofbiz/common/CommonServices .xml"/> 
            <response name="success" type="view" value="testServiceTest"/> 
            <response name="error" type="view" value="testServiceTest"/> 
    </request-map> 
    在event 中调用,且type为simple . 
    3.7. field-to-session 
      <field-to-session field="newUserLogin" session-name="userLogin"/> 
    Field-to-session 将simple 环境中的参数放入session 中。属性不重复了. 
    使用限制和session-to-field一样。 
      
       
    3.8. field-to-list 
    <clear-field field="newList"/> 
       <field-to-list list="newList" field="newUserLogin"/> 
    Field-to-list ,将simple 环境中的一个参数变量放到一个list 类型的参数变量中。 
    3.9. field-to-request 
    <clear-field field="newList"/> 
       <field-to-list list="newList" field="newUserLogin"/> 
      <field-to-request field="newList" request-name="userLoginList"/> 
    field-to-request ,把参数变量放到request 中,使用规则和限制同field-to-session 相同,不重复。 
    3.10. request-to-field 
    将参数从request 中取出赋职到simple 运行环境中。规则和限制同field-to-request。 
    3.11. request-parameters-to-list 
       <request-parameters-to-list request-name="checkBoxName" list-name="parametersList"/> 
    request-parameters-to-list 获取request 中的参数数组,并将参数放到simple method 中的list 中。request-parameters参数一般来源于checkBox .使用限制同 Session-to-field。
    3.12. list-to-list 
    待确定。 
    3.13. map-to-map 
    待确定。 

    3.14. loop 
    Loop待确定。 
    3.15. first-from-list 
    <first-from-list entry="oldExampleStatus" list="oldExampleStatusList"/> 
        <if-not-empty field="oldExampleStatus"> 
        <set field="oldExampleStatus.statusEndDate" from-field="nowTimestamp"/> 
        <store-value value-field="oldExampleStatus"/> 
    </if-not-empty> 
    first-from-list 从list 参数中得到第一个元素,并赋值到变量参数${entry}中。 
    3.16. webapp-property-to-field 
    <webapp-property-to-field resource="WebtoolsUiLabels" property="doNotHavePermission" field="fildFromProperties"/> 
    Webapp-property-to-field 从国际化资源文件WebtoolsUiLabel.xml中获取property 为” doNotHavePermission” 的字符串并赋值到${field}中。 

    3.17. iterate 

       <clear-field field="newParamList"/> 
       <set field="newParamList[]" value="a"/> 
       <set field="newParamList[]" value="b"/> 
       <set field="newParamList[]" value="c"/> 
       
    <iterate entry="newParam" list="newParamList" > 
    <log level="info" message="${newParam}"></log> 
    </iterate> 
    Iterate 遍历List参数newParamList。 
    3.18. iterate-map 
    <clear-field field="newParamMap"/> 
    <set field="newParamMap.param1" value="param1"/> 
    <set field="newParamMap.param2" value="param2"/> 
    <set field="newParamMap.param3" value="param3"/> 
    <iterate-map key="newKey" value="newValue" map="newParamMap"> 
    <log level="info" message="${newValue}"></log> 
    <log level="info" message="${newParamMap.${newKey}}"></log> 
    </iterate-map> 
    Iterate-map 对map参数进行遍历,这里有两种方法获取map中元素,一: 通过直接读取${value},二:也可以通过${key}读取map . 


    3.19. while 
    <set field="tmp" value="1"/> 
       <while> 
       <condition> 
       <if-compare operator="equals" value="2" field="tmp"> 
       </if-compare> 
       </condition> 
       <then> 
       <log level="info" message="test"></log> 
       </then> 
    </while> 
    While 循环,无论condition 条件 是否成立,先执行一次then 中的内容,然后再进行 condition 条件判断,如果不满足,则跳出while 循环。 
    3.20. refresh-value 
    refresh-value 待确定。 

    4. 调用 
    4.1. script 
    <script location="component://product/webapp/catalog/WEB-INF/actions/imag emanagement/SetDefaultImage.groovy"/> 
    Script 调用groovy 脚本 。 
    :error-list-name:错误信息存放参数名称 


    4.2. call-bsh 
    <call-bsh><![CDATA[ 
                taxAuthPartyGeoIds = parameters.get("taxAuthPartyGeoIds"); 
                parameters.put("taxAuthPartyId", taxAuthPartyGeoIds.substring(0, taxAuthPartyGeoIds.indexOf("::"))); 
                parameters.put("taxAuthGeoId", taxAuthPartyGeoIds.substring(taxAuthPartyGeoIds.indexOf("::") + 2)); 
            ]]> 
    </call-bsh> 
    使用CDATA 部件 直接调用bsh脚本。也可以直接调用bsh 文件。 
    <call-bsh error-list-name="error_list" resource="component://webtools/webapp/webtools/WEB-INF/actions/ca che/findUtilCache.bsh"> 
    </call-bsh> 


    4.3. call-class-method 
      <call-class-method class-name="org.ofbiz.base.util.UtilDateTime" method-name="getInterval" ret-field="originalProductionRunEstimatedTime"> 
    <field field="productionRunHeader.estimatedStartDate" type="Timestamp"/> 
        <field field="productionRunHeader.estimatedCompletionDate" type="Timestamp"/> 
    </call-class-method> 
    <set field="taskTimeDifference" value="${originalProductionRunEstimatedTime - newProductionRunEstimatedTime}" type="Double"/> 

      public static double getInterval(Date from, Date thru) { 
            return thru != null ? thru.getTime() - from.getTime() : 0; 
        } 

    call-class-method 调用class类中的方法 . 
    : class-name:class类所在路径。 
    :method-name:class类中方法名称。 
    :ret-field:返回值名称,如果ret-map-name 没有设置的话,直接从当前环境中获取此参数就可以了,如上例。 
    : ret-map-name:如果设置此值,那么需要先从simple methodContext中获取此map 对象,然后再从map 中获取ret-field. 
    : field:当前调用的方法所需要的参数。 

    4.4. call-map-processor 
    <call-map-processor xml-resource="component://accounting/script/org/ofbiz/accounting/ payment/PaymentMapProcs.xml" 
    processor-name="createCreditCard" in-map-name="parameters" out-map-name="context"/> 
    call-map-processor调用map 处理器。 
    map-processor 一种对map中元素进行过滤或者转化的处理器,类似于加工车间,入料口投入原料,出料口获得成品。一般多用于service 的参数进行处理,因为一般情况下service 对输入参数有限制,所以有时候需要对输入参数map 进行转化一下以匹配service 参数义。 
    :xml-resource:map-processor 路径。 
    :processor-name:map-processor名称。 
    :in-map-name:输入map名称,相当于入料口原料,可能包含多余的参数。 
    :out-map-name:输入map 名称,相当于出料口,获得到的map 可以直接用于service 的输入参数。 



    4.5. set-service-fields 
    <set-service-fields to-map="categoryFindContext" service-name="getAllCategories" map="parameters"/> 

    <call-service service-name="getAllCategories" in-map-name="categoryFindContext"> 
        <result-to-field result-name="categories" field="categories"/> 
    </call-service> 

    set-service-fields 功能同call-map-processor,都是对map中元素进行过滤处理。不同的是 call-map-processor 的处理规则是我们手动定义的map-processor规则,set-service-fields规则是使用service 定义的输入参数。 
    :service-name:service 名称。规定程序按照此service参数定义进行过滤。 
    :map:转换器入口,投入map 的名称。 
    :to-map:转换器出口,输出map的名称。 

    4.6. call-service 
    <call-service service-name="getAllCategories" in-map-name="categoryFindContext"> 
                <result-to-field result-name="categories" field="categoriesField"/> 
                <result-to-request result-name="categories" request-name="categoriesField"/> 
                <result-to-session result-name="categories" session-name="categoriesField"/> 
                <result-to-result result-name="categories" service-result-name="categoriesResult"/> 
            </call-service>
    call-service 
    经过call-map-processor 或 set-service-fields 参数处理之后,处理之后的输出结果, 我们可以直接拿来用做调用service 的输入参数。如上例: 
    :service-name:service 名称 
    :in-map-name:调用service 时用到的输入参数,map 类型,如果这里调用的是一个simple service的话 这里的in-map-name 就相当于 被调用simple service 中的parameters ,如果这里调用的是一个java service 的话这里的in-map-name 就相当于java service 输入参数中的context ,都是从其中获取参数。 
    :result-to-field:假设在service A 中调用 service B ,那么个配置是将B service 中的return 参数 赋值到 service A 的参数。result-name 一定要是service B 中定义过的输出参数。 
    :result-to-request:request-to-request  和 request-to-session 分别是将被调用service 的返回参数赋值到request 或者 session 中, 使用此命令有限制,请参考field-to-request。 
    :result-to-result: 将service B 的输出参数 赋值到service A 的输出参数中 
    result-name 一定要是 service B 中定义过的输出参数, service-result-name一定要是service A中定义过的输出参数。 

    4.7. call-service-asynch 
    call-service-asynch同call-service 类似,不同的是call-service是能够步调用,call-service-asynch 是异步调用,异步调用使用的ofbiz job 调度实现。 
    4.8. call-object-method 
    <set field="newString" value="123:456" type="String"/> 

    <call-object-method method-name="indexOf" obj-field="newString" ret-field="retObject"> 
    <string value=":"></string> 
    </call-object-method>    
    <log level="info" message="${retObject}"> 
    call-object-method 调用参数对象的方法。 
    :obj-field:参数对象名称。 
    :method-name:参数对象的方法名称。 
    :ret-field:返回值。 
    :string:输入参数。<string value=":"></string> 。field 同样是做为输入参数。 
    4.9. call-simple-method 
      <call-simple-method method-name="getGlArithmeticSettingsInline" xml-resource="component://accounting/script/org/ofbiz/accounting/ ledger/GeneralLedgerServices.xml"/> 

    call-simple-method 直接调用simple method ,不是以service 的形式调用。如果被调用simple-method 与当前service 在同一个xml文件中xml-resource 可以不用写。 
    5. 其他 
    5.1. now-date-to-env 
    <now-date-to-env field="nowDate"/> 
    将当前日期(不带时间)赋值给变量参数now.格式为yyyy-MM-dd 
       
    5.2. now-timestamp 
       <now-timestamp field="nowTime"/> 
    将当前日期时间赋值给变量参数nowTime,格式为yyyy-MM-dd HH:mm:ss.sss 
    5.3. to-string 
    将参数转化成string 格式。待确定。 
    5.4. log 
    输出日志。前面已经用到很多了 ,不重复了 。 

    5.5. Order-map-list 
    <clear-field field="newParamMap"/> 
    <set field="newParamMap.param1" value="param1"/> 
    <set field="newParamMap.param2" value="param2"/> 
    <set field="newParamMap.param3" value="param3"/> 

    <clear-field field="newParamMap1"/> 
    <set field="newParamMap1.param1" value="param4"/> 
    <set field="newParamMap1.param2" value="param5"/> 
    <set field="newParamMap1.param3" value="param6"/> 

    <clear-field field="newParamMap2"/> 
    <set field="newParamMap2.param1" value="param7"/> 
    <set field="newParamMap2.param2" value="param8"/> 
    <set field="newParamMap2.param3" value="param9"/> 


    <set field="newList[]" from-field="newParamMap"/> 
    <set field="newList[]" from-field="newParamMap1"/> 
    <set field="newList[]" from-field="newParamMap2"/> 

    <order-map-list list="newList" > 
    <order-by field-name="-param1"/> 
    </order-map-list> 
    <log level="info" message="${newList}"></log> 
    order-map-list 以一个list 中map的key为标准对这个list 中各个map 进行排序。 

    5.6. order-value-list 
    order-value-list 待定。 

    5.7. transaction-begin 

    开启事务。 
    :began-transaction-name:对当前事务取个别名,如果只有一个事务的话,可以使用默认值。 
    5.8. transaction-commit 
    提交事务,如果有多个事务可以根据began-transaction-name进行选择事务提交。 

    5.9. transaction-rollback 
    事务回滚。如果有多个事务可以根据began-transaction-name进行选择事务回滚。 

  • 相关阅读:
    【转】Math.Atan2 方法
    【转】Excel快捷键大全
    Tricks(四十七)—— 布尔矩阵(0-1矩阵)取反
    Tricks(四十七)—— 布尔矩阵(0-1矩阵)取反
    tensorflow 函数接口的理解
    tensorflow 函数接口的理解
    TensorFlow 学习(十一)—— 正则(regularizer)
    TensorFlow 学习(十一)—— 正则(regularizer)
    TensorFlow 需注意的细节问题
    TensorFlow 需注意的细节问题
  • 原文地址:https://www.cnblogs.com/lovenan/p/3253067.html
Copyright © 2020-2023  润新知