zoukankan      html  css  js  c++  java
  • 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进行选择事务回滚。 

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/lovenan/p/3253067.html
Copyright © 2011-2022 走看看